- forty files that carried the reference's literal Lua are rewritten as our own expression of the behaviour — worst identical run 61 lines down to 7 — and the README now says exactly that - the overlap gate measures the code itself across all four reference corpora, and ratchets: the number may only go down - a lost session ends at the login screen instead of silently re-authenticating and stealing the account back - a building's skybox is a real model: Caverns of Time's white ceiling becomes its painted nebula and additive stars Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
396 lines
22 KiB
XML
396 lines
22 KiB
XML
<Ui>
|
||
<!--
|
||
The item-text reader — letters, books, plaques (the mail arc's "permanent copy" lands
|
||
here). The Lua below is OURS; the reference ItemTextFrame.xml (354 l) + ItemTextFrame.lua
|
||
(104 l) are the SPECIFICATION it satisfies — frame/region names, the event flow, the
|
||
material art paths and the geometry/art are the reference's and are quoted as such.
|
||
Driven by the engine's item-text seam (benilla-ui/src/script/item_text.rs) +
|
||
crate::ui_item_text's feed/drain: the app fires the reference event flow
|
||
ITEM_TEXT_BEGIN → ITEM_TEXT_READY → ITEM_TEXT_CLOSED.
|
||
|
||
ADAPTATIONS (the MailFrame.xml precedents):
|
||
· The body scroll (ItemTextScrollFrame, UIPanelScrollFrameTemplate 280×355 at -66,-76) is
|
||
a plain Frame at that exact rect with the page FontString INSIDE it (no live scrollbar);
|
||
a very long page clips. The ref's own flanking scrollbar art (UI-Character-ScrollBar
|
||
top/bottom + the black middle strip) is quoted verbatim as inert layers, so the right
|
||
edge reads exactly like the reference at rest.
|
||
· ItemTextPageText is SimpleHTML in the ref — drawn here as a FontString at the same
|
||
rect (our letters/pages are plain text; an HTML page renders as its markup, accepted).
|
||
· The ScrollFrame-only verbs the reference's OnLoad/READY use (UpdateScrollChildRect,
|
||
ScrollBar SetValue/Hide, scrollBarHideable) are dropped with the live scrollbar.
|
||
· The two material colour TABLES are the reference's data (its Fonts.xml), quoted
|
||
verbatim — the numbers ARE the look. They live here Benilla-scoped (the MoneyInput-shim
|
||
precedent) because our own Fonts.xml deliberately doesn't ship the reference's two
|
||
globals; the lookup around them is ours, under the reference's published name.
|
||
· GlobalStrings inlined: PREV "Prev", NEXT "Next", ITEM_TEXT_FROM "From," (the reference
|
||
string really is comma'd).
|
||
· ITEM_TEXT_TRANSLATION (the foreign-language progress bar) is implemented but never
|
||
fires — no translation mechanic on our letters; the StatusBar stays hidden.
|
||
· <HitRectInsets> quoted verbatim for fidelity but currently inert (the loader ignores
|
||
the element).
|
||
-->
|
||
<Script><![CDATA[
|
||
-- ── The material palette ─────────────────────────────────────────────────────────────
|
||
-- The six materials a page can be printed on, and the ink each one takes. The COLOURS are
|
||
-- the reference's own data (its Fonts.xml l.27-42) and are quoted verbatim: a different
|
||
-- number is a different look. Benilla-scoped names — see the header.
|
||
BENILLA_MATERIAL_TEXT_COLOR_TABLE = {
|
||
["Default"] = {0.18, 0.12, 0.06},
|
||
["Stone"] = {1.0, 1.0, 1.0},
|
||
["Parchment"] = {0.18, 0.12, 0.06},
|
||
["Marble"] = {0, 0, 0},
|
||
["Silver"] = {0.12, 0.12, 0.12},
|
||
["Bronze"] = {0.18, 0.12, 0.06}
|
||
}
|
||
BENILLA_MATERIAL_TITLETEXT_COLOR_TABLE = {
|
||
["Default"] = {0, 0, 0},
|
||
["Stone"] = {0.93, 0.82, 0},
|
||
["Parchment"] = {0, 0, 0},
|
||
["Marble"] = {0.93, 0.82, 0},
|
||
["Silver"] = {0.93, 0.82, 0},
|
||
["Bronze"] = {0.93, 0.82, 0}
|
||
}
|
||
-- The page ink and the title ink for a material, under the reference's published name
|
||
-- (its UIParent.lua l.1880-1888). Falls back to "Default" unless BOTH halves are known, so
|
||
-- an unrecognised material never gets one table's colour and the other's default.
|
||
function GetMaterialTextColors(material)
|
||
local textColor = BENILLA_MATERIAL_TEXT_COLOR_TABLE[material]
|
||
local titleColor = BENILLA_MATERIAL_TITLETEXT_COLOR_TABLE[material]
|
||
if not (textColor and titleColor) then
|
||
textColor = BENILLA_MATERIAL_TEXT_COLOR_TABLE["Default"]
|
||
titleColor = BENILLA_MATERIAL_TITLETEXT_COLOR_TABLE["Default"]
|
||
end
|
||
return textColor, titleColor
|
||
end
|
||
|
||
-- ── The reader's regions, by role ────────────────────────────────────────────────────
|
||
-- The four material corners are one SET: a page is either bare parchment (all four off)
|
||
-- or dressed in a material, in which case each corner wears that material's own art.
|
||
-- Naming the suffixes once is also what makes the art path a single expression.
|
||
local MATERIAL_CORNERS = { "TopLeft", "TopRight", "BotLeft", "BotRight" }
|
||
|
||
-- Everything a fresh ITEM_TEXT_BEGIN clears away. At that point only the title is known,
|
||
-- so only the title stays on screen — the page and all of its paging chrome go.
|
||
local PAGE_CHROME = {
|
||
"ItemTextScrollFrame", "ItemTextCurrentPage", "ItemTextStatusBar",
|
||
"ItemTextPrevPageButton", "ItemTextNextPageButton",
|
||
}
|
||
|
||
local function ShowOrHide(region, wanted)
|
||
if wanted then
|
||
region:Show()
|
||
else
|
||
region:Hide()
|
||
end
|
||
end
|
||
|
||
-- A page always HAS a material: the server may name none, and the frame's own art is
|
||
-- already parchment, so that is what "none" means.
|
||
local function PageMaterial()
|
||
return ItemTextGetMaterial() or "Parchment"
|
||
end
|
||
|
||
-- Dress the page's four corners in its material. Parchment IS the frame's own art, so
|
||
-- parchment leaves the corners off and lets the bare frame show through; anything else
|
||
-- lights all four and points each at its own slice of that material's art set.
|
||
local function DressPage(material)
|
||
if material == "Parchment" then
|
||
for _, corner in ipairs(MATERIAL_CORNERS) do
|
||
getglobal("ItemTextMaterial" .. corner):Hide()
|
||
end
|
||
return
|
||
end
|
||
local art = "Interface\\ItemTextFrame\\ItemText-" .. material .. "-"
|
||
for _, corner in ipairs(MATERIAL_CORNERS) do
|
||
local layer = getglobal("ItemTextMaterial" .. corner)
|
||
layer:Show()
|
||
layer:SetTexture(art .. corner)
|
||
end
|
||
end
|
||
|
||
-- Put the reader on screen. The panel manager is allowed to refuse (something
|
||
-- native-center is holding the screen) — and then we are not reading after all, so the
|
||
-- server has to be told, or the session stays open behind a window that never appeared.
|
||
-- The reference makes the same check, on both of the paths that open this window.
|
||
local function OpenReader(frame)
|
||
ShowUIPanel(frame)
|
||
if not frame:IsVisible() then
|
||
CloseItemText()
|
||
end
|
||
end
|
||
|
||
-- ── The event flow ───────────────────────────────────────────────────────────────────
|
||
-- One function per event of the reference's flow: ItemTextFrame_OnLoad registers FLOW in
|
||
-- order and ItemTextFrame_OnEvent dispatches into Handlers by name. (The reference states
|
||
-- the same pairing twice — four RegisterEvent calls, then a four-arm `if event == …`
|
||
-- chain — which is how a fifth event gets added to one of them and not the other.)
|
||
local FLOW = {
|
||
"ITEM_TEXT_BEGIN", "ITEM_TEXT_TRANSLATION", "ITEM_TEXT_READY", "ITEM_TEXT_CLOSED",
|
||
}
|
||
local Handlers = {}
|
||
|
||
-- A text has been opened. Only its title is known yet, so the page is cleared away and
|
||
-- the ink is set for the material the pages are going to arrive on.
|
||
function Handlers.ITEM_TEXT_BEGIN(frame)
|
||
ItemTextTitleText:SetText(ItemTextGetItem())
|
||
for _, name in ipairs(PAGE_CHROME) do
|
||
getglobal(name):Hide()
|
||
end
|
||
local ink = GetMaterialTextColors(PageMaterial())
|
||
ItemTextPageText:SetTextColor(ink[1], ink[2], ink[3])
|
||
end
|
||
|
||
-- A foreign-language page is being translated: the turn buttons stand down and the
|
||
-- progress bar takes over, ranged across the arg1 seconds the server quoted (OnUpdate
|
||
-- fills it). Never fires on our letters — see the header.
|
||
function Handlers.ITEM_TEXT_TRANSLATION(frame)
|
||
ItemTextPrevPageButton:Hide()
|
||
ItemTextNextPageButton:Hide()
|
||
frame.translationElapsed = 0
|
||
ItemTextStatusBar:SetMinMaxValues(0, arg1)
|
||
ItemTextStatusBar:Show()
|
||
OpenReader(frame)
|
||
end
|
||
|
||
-- A page has arrived. A letter signs off with its sender (ITEM_TEXT_FROM — the reference
|
||
-- string really is comma'd); anything else just gets its trailing blank line. The paging
|
||
-- row appears only when there is another page to be on, and then each button shows only
|
||
-- if there is something in its direction.
|
||
function Handlers.ITEM_TEXT_READY(frame)
|
||
local creator = ItemTextGetCreator()
|
||
local body = "\n" .. ItemTextGetText()
|
||
if creator then
|
||
body = body .. "\n\n" .. "From," .. "\n" .. creator .. "\n\n"
|
||
else
|
||
body = body .. "\n"
|
||
end
|
||
ItemTextPageText:SetText(body)
|
||
ItemTextScrollFrame:Show()
|
||
|
||
local pageNumber = ItemTextGetPage()
|
||
local hasNext = ItemTextHasNextPage()
|
||
DressPage(PageMaterial())
|
||
if pageNumber > 1 or hasNext then
|
||
ItemTextCurrentPage:SetText(pageNumber)
|
||
ItemTextCurrentPage:Show()
|
||
ShowOrHide(ItemTextPrevPageButton, pageNumber > 1)
|
||
ShowOrHide(ItemTextNextPageButton, hasNext)
|
||
end
|
||
ItemTextStatusBar:Hide()
|
||
OpenReader(frame)
|
||
end
|
||
|
||
function Handlers.ITEM_TEXT_CLOSED(frame)
|
||
HideUIPanel(frame)
|
||
end
|
||
|
||
function ItemTextFrame_OnLoad()
|
||
for _, event in ipairs(FLOW) do
|
||
this:RegisterEvent(event)
|
||
end
|
||
end
|
||
|
||
function ItemTextFrame_OnEvent(event)
|
||
local handler = Handlers[event]
|
||
if handler then
|
||
handler(this)
|
||
end
|
||
end
|
||
|
||
-- The translation bar's clock: while the bar is up it fills with the seconds spent so far.
|
||
function ItemTextFrame_OnUpdate(elapsed)
|
||
if not ItemTextStatusBar:IsVisible() then
|
||
return
|
||
end
|
||
local spent = this.translationElapsed + elapsed
|
||
ItemTextStatusBar:SetValue(spent)
|
||
this.translationElapsed = spent
|
||
end
|
||
|
||
-- Both page buttons are one gesture in two directions: the paging click, then the
|
||
-- engine's own page request. `turnPage` is ItemTextPrevPage or ItemTextNextPage.
|
||
function ItemTextFrame_TurnPage(turnPage)
|
||
PlaySound("igMainMenuOptionCheckBoxOn")
|
||
turnPage()
|
||
end
|
||
]]></Script>
|
||
<Frame name="ItemTextFrame" toplevel="true" movable="true" enableMouse="true" hidden="true" parent="UIParent">
|
||
<Size><AbsDimension x="384" y="512"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-104"/></Offset></Anchor></Anchors>
|
||
<HitRectInsets><AbsInset left="0" right="30" top="0" bottom="70"/></HitRectInsets>
|
||
<Layers>
|
||
<Layer level="BACKGROUND">
|
||
<Texture file="Interface\Spellbook\Spellbook-Icon">
|
||
<Size><AbsDimension x="58" y="58"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="10" y="-8"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="BORDER">
|
||
<Texture file="Interface\ItemTextFrame\UI-ItemText-TopLeft">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\Spellbook\UI-SpellbookPanel-TopRight">
|
||
<Size><AbsDimension x="128" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="256" y="0"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\ItemTextFrame\UI-ItemText-BotLeft">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-256"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture file="Interface\Spellbook\UI-SpellbookPanel-BotRight">
|
||
<Size><AbsDimension x="128" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="256" y="-256"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="ARTWORK">
|
||
<!-- The non-parchment material corners (stone/marble/…): textures swapped in by
|
||
ITEM_TEXT_READY; hidden entirely for parchment (ref l.56-70). -->
|
||
<Texture name="ItemTextMaterialTopLeft" hidden="true">
|
||
<Size><AbsDimension x="256" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="21" y="-75"/></Offset></Anchor></Anchors>
|
||
</Texture>
|
||
<Texture name="ItemTextMaterialTopRight" hidden="true">
|
||
<Size><AbsDimension x="64" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="ItemTextMaterialTopLeft" relativePoint="TOPRIGHT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="ItemTextMaterialBotLeft" hidden="true">
|
||
<Size><AbsDimension x="256" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="ItemTextMaterialTopLeft" relativePoint="BOTTOMLEFT"/></Anchors>
|
||
</Texture>
|
||
<Texture name="ItemTextMaterialBotRight" hidden="true">
|
||
<Size><AbsDimension x="64" y="128"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativeTo="ItemTextMaterialTopLeft" relativePoint="BOTTOMRIGHT"/></Anchors>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="OVERLAY">
|
||
<FontString name="ItemTextTitleText" inherits="GameFontNormal">
|
||
<Size><AbsDimension x="224" y="14"/></Size>
|
||
<Anchors><Anchor point="CENTER"><Offset><AbsDimension x="6" y="230"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
<FontString name="ItemTextCurrentPage" inherits="GameFontNormal">
|
||
<Size><AbsDimension x="192" y="0"/></Size>
|
||
<Anchors><Anchor point="TOP"><Offset><AbsDimension x="10" y="-50"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Frames>
|
||
<!-- ref ItemTextScrollFrame l.145-219: the plain-Frame stand-in (see the header) with
|
||
the ref's own flanking scrollbar art kept verbatim. -->
|
||
<Frame name="ItemTextScrollFrame" hidden="true">
|
||
<Size><AbsDimension x="280" y="355"/></Size>
|
||
<Anchors><Anchor point="TOPRIGHT"><Offset><AbsDimension x="-66" y="-76"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<!-- The ref declares ARTWORK before BACKGROUND here, and the order is
|
||
load-bearing: Middle anchors to Top by name, and anchors resolve at
|
||
SetPoint time — a target declared later falls back to the parent (and
|
||
the black track lands on the parchment). -->
|
||
<Layer level="ARTWORK">
|
||
<Texture name="ItemTextScrollFrameTop" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
|
||
<Size><AbsDimension x="28" y="256"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT" relativePoint="TOPRIGHT"><Offset><AbsDimension x="0" y="5"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0" right="0.484375" top="0" bottom="1.0"/>
|
||
</Texture>
|
||
<Texture name="ItemTextScrollFrameBottom" file="Interface\PaperDollInfoFrame\UI-Character-ScrollBar">
|
||
<Size><AbsDimension x="28" y="107"/></Size>
|
||
<Anchors><Anchor point="BOTTOMLEFT" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-3"/></Offset></Anchor></Anchors>
|
||
<TexCoords left="0.515625" right="1.0" top="0" bottom="0.4140625"/>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="BACKGROUND">
|
||
<Texture name="ItemTextScrollFrameMiddle">
|
||
<Size><AbsDimension x="25" y="365"/></Size>
|
||
<Anchors><Anchor point="TOPRIGHT" relativeTo="ItemTextScrollFrameTop"/></Anchors>
|
||
<Color r="0" g="0" b="0" a="0.8"/>
|
||
</Texture>
|
||
</Layer>
|
||
<Layer level="OVERLAY">
|
||
<!-- ref ItemTextPageText (SimpleHTML 270×304 at 0,-15 in the scroll child)
|
||
as a FontString at the same rect. -->
|
||
<FontString name="ItemTextPageText" inherits="ItemTextFontNormal" justifyH="LEFT" justifyV="TOP">
|
||
<Size><AbsDimension x="270" y="304"/></Size>
|
||
<Anchors><Anchor point="TOPLEFT"><Offset><AbsDimension x="0" y="-15"/></Offset></Anchor></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
</Frame>
|
||
<!-- ref ItemTextStatusBar l.220-251 — the ITEM_TEXT_TRANSLATION progress bar; never
|
||
fires on our letters, kept for fidelity. -->
|
||
<StatusBar name="ItemTextStatusBar" hidden="true">
|
||
<Size><AbsDimension x="250" y="21"/></Size>
|
||
<Anchors><Anchor point="BOTTOM" relativeTo="ItemTextFrame"><Offset><AbsDimension x="-5" y="128"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<Layer level="OVERLAY">
|
||
<Texture file="Interface\PaperDollInfoFrame\UI-Character-Skills-BarBorder">
|
||
<Size><AbsDimension x="256" y="23"/></Size>
|
||
<Anchors><Anchor point="CENTER"/></Anchors>
|
||
<TexCoords left="0" right="1.0" top="0.0625" bottom="0.75"/>
|
||
</Texture>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnLoad>this:SetFrameLevel(this:GetFrameLevel()+1)</OnLoad>
|
||
</Scripts>
|
||
<BarTexture file="Interface\TargetingFrame\UI-TargetingFrame-BarFill"/>
|
||
<BarColor r="0.25" g="0.75" b="0.25"/>
|
||
</StatusBar>
|
||
<Button name="ItemTextPrevPageButton" hidden="true">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPLEFT"><Offset><AbsDimension x="90" y="-56"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString inherits="GameFontNormal" justifyH="LEFT" text="Prev"><!-- PREV -->
|
||
<Anchors><Anchor point="LEFT" relativePoint="RIGHT"/></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnClick>ItemTextFrame_TurnPage(ItemTextPrevPage)</OnClick>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Up"/>
|
||
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Down"/>
|
||
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
<Button name="ItemTextNextPageButton" hidden="true">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-55" y="-56"/></Offset></Anchor></Anchors>
|
||
<Layers>
|
||
<Layer level="ARTWORK">
|
||
<FontString inherits="GameFontNormal" justifyH="RIGHT" text="Next"><!-- NEXT -->
|
||
<Anchors><Anchor point="RIGHT" relativePoint="LEFT"/></Anchors>
|
||
</FontString>
|
||
</Layer>
|
||
</Layers>
|
||
<Scripts>
|
||
<OnClick>ItemTextFrame_TurnPage(ItemTextNextPage)</OnClick>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Up"/>
|
||
<PushedTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Down"/>
|
||
<DisabledTexture file="Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Common-MouseHilight" alphaMode="ADD"/>
|
||
</Button>
|
||
<Button name="ItemTextCloseButton">
|
||
<Size><AbsDimension x="32" y="32"/></Size>
|
||
<Anchors><Anchor point="CENTER" relativePoint="TOPRIGHT"><Offset><AbsDimension x="-45" y="-26"/></Offset></Anchor></Anchors>
|
||
<Scripts>
|
||
<OnClick>HideUIPanel(ItemTextFrame)</OnClick>
|
||
</Scripts>
|
||
<NormalTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Up"/>
|
||
<PushedTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Down"/>
|
||
<HighlightTexture file="Interface\Buttons\UI-Panel-MinimizeButton-Highlight" alphaMode="ADD"/>
|
||
</Button>
|
||
</Frames>
|
||
<Scripts>
|
||
<OnLoad>ItemTextFrame_OnLoad()</OnLoad>
|
||
<OnEvent>ItemTextFrame_OnEvent(event)</OnEvent>
|
||
<OnUpdate>ItemTextFrame_OnUpdate(arg1)</OnUpdate>
|
||
<OnShow>PlaySound("igMainMenuOpen")</OnShow>
|
||
<OnHide>
|
||
CloseItemText()
|
||
PlaySound("igMainMenuClose")
|
||
</OnHide>
|
||
</Scripts>
|
||
</Frame>
|
||
</Ui>
|