[Scummvm-git-logs] scummvm master -> ffbefea20ca85f05590d1c46a68f3e2de7131c13

sev- noreply at scummvm.org
Tue Feb 4 14:24:36 UTC 2025


This automated email contains information about 34 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
feffecff0c DIRECTOR: Improve support for rendering trails
c75b75bec1 DIRECTOR: Move ownership of Windows to DirectorEngine
47fdf67b74 DIRECTOR: Add debugger command for listing windows
5f336ea402 DIRECTOR: XOBJ: Add additional functions for HenryXObj
151d52f938 DIRECTOR: Move Lingo stack into LingoState, fix c_tell infinite loops
a78f0285d2 DIRECTOR: Director 5 Lingo parser additions
afdc7a91fa DIRECTOR: Add entities/fields new to Director 5
43b63504c7 DIRECTOR: Update detection entry for ukiuki1
007c3e687b DIRECTOR: Track timeout figures as signed integer
39c252e993 DIRECTOR: Fix multiplexed cast member ID handling
753ea882c5 DIRECTOR: Add entities/fields new to Director 5
8d8c578b9e DIRECTOR: Add German version of winniewitch to detection table
cdccd3b997 DIRECTOR: Add void check for actor perFrameHooks
520d9dcedf DIRECTOR: XOBJ: Add stubs for PrintOMatic, FileXtra and Xsound
c4a3134d9b DIRECTOR: Add detection entry for Plates are People Too!
ab5eb6425f DEVTOOLS: Add textfile support to director-generate-xobj-stub.py
5003d8769f DIRECTOR: LINGO: Improve support for D5-style CastMemberID decoding
2397091adf DIRECTOR: LINGO: Add stubs for new D5 builtin functions
a529f6db4d DIRECTOR: Add entities/fields new to Director 5
0005d43144 DIRECTOR: LINGO: Mark new event types
c0df58acc8 DIRECTOR: XOBJ: Implement m_readPict in FileIO
c4bd70d820 DIRECTOR: Fix name remapping when duplicating a cast member
2d58f99fd6 DIRECTOR: Overhaul TextCastMember
7362ec3cb1 DIRECTOR: Fix libResourceID usage for multiple casts
57f478fa03 DIRECTOR: Fix castLib object properties
a26372cd2e DIRECTOR: Improve support for parsing multiplexed CastMemberIDs
c967f946a7 DIRECTOR: Add new properties for SoundCastMember
04d5c36679 DIRECTOR: Add new properties for ShapeCastMember
f40f9fdada DIRECTOR: Add the castLibNum sprite property
28a17b245f DIRECTOR: Add new properties for MovieCastMember
195ecca491 DIRECTOR: Add the paletteRef BitmapCastMember property
098aef847f DIRECTOR: Add new properties for DigitalVideoCastMember
88bf79d942 DIRECTOR: Add D5 bodge for 'type of member'
ffbefea20c DIRECTOR: Add new properties for ScriptCastMember


Commit: feffecff0c1f28b99530d2f2997dd6151e434064
    https://github.com/scummvm/scummvm/commit/feffecff0c1f28b99530d2f2997dd6151e434064
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Improve support for rendering trails

Changed paths:
    engines/director/window.cpp


diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 6ec6194ab32..2cabda15c78 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -169,15 +169,22 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
 		_dirtyChannels = _currentMovie->getScore()->getSpriteIntersections(r);
 
 		bool shouldClear = true;
+		Channel *trailChannel = nullptr;
 		for (auto &j : _dirtyChannels) {
 			if (j->_visible && r == j->getBbox() && j->isTrail()) {
 				shouldClear = false;
+				trailChannel = j;
 				break;
 			}
 		}
 
-		if (shouldClear)
+		if (shouldClear) {
 			blitTo->fillRect(r, _stageColor);
+		} else if (trailChannel) {
+			// Trail rendering mode; do not re-render the background and sprites underneath.
+			_dirtyChannels.clear();
+			_dirtyChannels.push_back(trailChannel);
+		}
 
 		for (int pass = 0; pass < 2; pass++) {
 			for (auto &j : _dirtyChannels) {


Commit: c75b75bec167269cb7535651037df99c4dd01976
    https://github.com/scummvm/scummvm/commit/c75b75bec167269cb7535651037df99c4dd01976
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Move ownership of Windows to DirectorEngine

Changed paths:
    engines/director/director.cpp
    engines/director/director.h
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-object.cpp


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index b6ab75f803b..5eb596d9ad4 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -83,9 +83,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	memset(_currentPalette, 0, 768);
 	_currentPaletteLength = 0;
 	_stage = nullptr;
-	_windowList = new Datum;
-	_windowList->type = ARRAY;
-	_windowList->u.farr = new FArray;
 	_currentWindow = nullptr;
 	_cursorWindow = nullptr;
 	_lingo = nullptr;
@@ -155,7 +152,9 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 }
 
 DirectorEngine::~DirectorEngine() {
-	delete _windowList;
+	for (auto &it : _windowList) {
+		it->decRefCount();
+	}
 	delete _lingo;
 	delete _wm;
 	delete _surface;
@@ -184,6 +183,32 @@ Common::String DirectorEngine::getCurrentAbsolutePath() {
 
 static bool buildbotErrorHandler(const char *msg) { return true; }
 
+Window *DirectorEngine::getOrCreateWindow(Common::String &name) {
+	for (auto &it : _windowList) {
+		if (it->getName().equalsIgnoreCase(name)) {
+			return it;
+		}
+	}
+	Window *window = new Window(_wm->getNextId(), false, false, false, _wm, g_director, false);
+	window->setName(name);
+	window->setTitle(name);
+	window->resizeInner(1, 1);
+	window->setVisible(false, true);
+	_wm->addWindowInitialized(window);
+	_windowList.push_back(window);
+	window->incRefCount();
+	return window;
+}
+
+void DirectorEngine::forgetWindow(Window *window) {
+	for (auto &it : _windowsToForget) {
+		if (it == window)
+			return;
+	}
+	window->setVisible(false, true);
+	_windowsToForget.push_back(window);
+}
+
 void DirectorEngine::setCurrentWindow(Window *window) {
 	if (_currentWindow == window)
 		return;
@@ -311,18 +336,26 @@ Common::Error DirectorEngine::run() {
 		loop = _currentWindow->step();
 
 		if (loop) {
-			FArray *windowList = g_lingo->_windowList.u.farr;
-			for (uint i = 0; i < windowList->arr.size(); i++) {
-				if (windowList->arr[i].type != OBJECT || windowList->arr[i].u.obj->getObjType() != kWindowObj)
-					continue;
-
-				setCurrentWindow(static_cast<Window *>(windowList->arr[i].u.obj));
+			for (auto &it : _windowList) {
+				setCurrentWindow(it);
 				g_lingo->switchStateFromWindow();
 				_currentWindow->step();
 			}
 		}
 
 		draw();
+		while (!_windowsToForget.empty()) {
+			Window *window = _windowsToForget.back();
+			_windowsToForget.pop_back();
+			for (size_t i = 0; i < _windowList.size(); i++) {
+				if (_windowList[i] == window) {
+					_windowList.remove_at(i);
+					window->decRefCount();
+					break;
+				}
+			}
+		}
+
 		g_director->delayMillis(10);
 #ifdef USE_IMGUI
 		// For performance reasons, disable the renderer callback if the ImGui debug flag isn't set
diff --git a/engines/director/director.h b/engines/director/director.h
index 44a79a48cd7..d45752dc124 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -174,6 +174,8 @@ public:
 	Lingo *getLingo() const { return _lingo; }
 	Window *getStage() const { return _stage; }
 	Window *getCurrentWindow() const { return _currentWindow; }
+	Window *getOrCreateWindow(Common::String &name);
+	void forgetWindow(Window *window);
 	void setCurrentWindow(Window *window);
 	Window *getCursorWindow() const { return _cursorWindow; }
 	void setCursorWindow(Window *window) { _cursorWindow = window; }
@@ -300,7 +302,8 @@ private:
 	uint16 _version;
 
 	Window *_stage;
-	Datum *_windowList; // Lingo list
+	Common::Array<Window *> _windowList;
+	Common::Array<Window *> _windowsToForget;
 	Window *_currentWindow;
 	Window *_cursorWindow;
 
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index d60010d16e8..4b38569ea27 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3450,20 +3450,8 @@ void LB::b_script(int nargs) {
 
 void LB::b_window(int nargs) {
 	Datum d = g_lingo->pop();
-	Common::String windowName = d.asString();
 	FArray *windowList = g_lingo->_windowList.u.farr;
 
-	for (uint i = 0; i < windowList->arr.size(); i++) {
-		if (windowList->arr[i].type != OBJECT || windowList->arr[i].u.obj->getObjType() != kWindowObj)
-			continue;
-
-		Window *window = static_cast<Window *>(windowList->arr[i].u.obj);
-		if (window->getName().equalsIgnoreCase(windowName)) {
-			g_lingo->push(window);
-			return;
-		}
-	}
-
 	// Refer window by-indexing, lingo can request using "window #index" where #index is the index of window that is previously
 	// created, in tutorial workshop `rect of window`, a window is created using 'open(window "ball")' and the same window is
 	// referenced by 'window 1', ie 'put the rect of window 1 into field 9'
@@ -3481,14 +3469,10 @@ void LB::b_window(int nargs) {
 		}
 	}
 
-	Graphics::MacWindowManager *wm = g_director->getMacWindowManager();
-	Window *window = new Window(wm->getNextId(), false, false, false, wm, g_director, false);
-	window->setName(windowName);
-	window->setTitle(windowName);
-	window->resizeInner(1, 1);
-	window->setVisible(false, true);
-	wm->addWindowInitialized(window);
-	windowList->arr.push_back(window);
+	Common::String windowName = d.asString();
+	Window *window = g_director->getOrCreateWindow(windowName);
+	windowList->arr.push_back(Datum(window));
+
 	g_lingo->push(window);
 }
 
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 201b713c0d9..6ada42159d1 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -825,7 +825,7 @@ void LM::m_forget(int nargs) {
 		if (it._value.u.obj == me)
 			g_lingo->_globalvars[it._key] = 0;
 	}
-
+	g_director->forgetWindow(me);
 }
 
 void LM::m_open(int nargs) {


Commit: 47fdf67b7410b4a99943ecc154c6c93b006508eb
    https://github.com/scummvm/scummvm/commit/47fdf67b7410b4a99943ecc154c6c93b006508eb
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add debugger command for listing windows

Changed paths:
    engines/director/debugger.cpp
    engines/director/debugger.h
    engines/director/director.cpp
    engines/director/director.h
    engines/director/window.cpp
    engines/director/window.h


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 76c82ae443a..192c539fcb1 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -87,6 +87,8 @@ Debugger::Debugger(): GUI::Debugger() {
 	registerCmd("fin", WRAP_METHOD(Debugger, cmdFinish));
 	registerCmd("continue", WRAP_METHOD(Debugger, cmdExit));
 	registerCmd("c", WRAP_METHOD(Debugger, cmdExit));
+	registerCmd("windows", WRAP_METHOD(Debugger, cmdWindows));
+	registerCmd("w", WRAP_METHOD(Debugger, cmdWindows));
 
 	registerCmd("bpset", WRAP_METHOD(Debugger, cmdBpSet));
 	registerCmd("b", WRAP_METHOD(Debugger, cmdBpSet));
@@ -165,6 +167,7 @@ bool Debugger::cmdHelp(int argc, const char **argv) {
 	debugPrintf(" next / n [n] - Steps forward one or more operations, skips over calls\n");
 	debugPrintf(" finish / fin - Steps until the current stack frame returns\n");
 	debugPrintf(" continue / c - Continues execution\n");
+	debugPrintf(" windows / w - Lists all of the windows\n");
 	debugPrintf("\n");
 	debugPrintf("Breakpoints:\n");
 	debugPrintf(" bpset / b - Creates a breakpoint at the current Lingo function and offset\n");
@@ -670,6 +673,16 @@ bool Debugger::cmdFinish(int argc, const char **argv) {
 	return cmdExit(0, nullptr);
 }
 
+bool Debugger::cmdWindows(int argc, const char **argv) {
+	debugPrintf("Stage:\n%s\n\n", g_director->getStage()->formatWindowInfo().c_str());
+	debugPrintf("Windows:\n");
+	for (auto &it : *g_director->getWindowList()) {
+		debugPrintf("%s\n", it->formatWindowInfo().c_str());
+	}
+	debugPrintf("\n");
+	return true;
+}
+
 bool Debugger::cmdBpSet(int argc, const char **argv) {
 	Breakpoint bp;
 	bp.type = kBreakpointFunction;
diff --git a/engines/director/debugger.h b/engines/director/debugger.h
index 4b8dd42b1fb..a214bfecac2 100644
--- a/engines/director/debugger.h
+++ b/engines/director/debugger.h
@@ -106,6 +106,7 @@ private:
 	bool cmdStep(int argc, const char **argv);
 	bool cmdNext(int argc, const char **argv);
 	bool cmdFinish(int argc, const char **argv);
+	bool cmdWindows(int argc, const char **argv);
 
 	bool cmdBpSet(int argc, const char **argv);
 	bool cmdBpMovie(int argc, const char **argv);
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 5eb596d9ad4..463521dfb6c 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -194,9 +194,10 @@ Window *DirectorEngine::getOrCreateWindow(Common::String &name) {
 	window->setTitle(name);
 	window->resizeInner(1, 1);
 	window->setVisible(false, true);
+	window->move(0, 0);
+	window->incRefCount();
 	_wm->addWindowInitialized(window);
 	_windowList.push_back(window);
-	window->incRefCount();
 	return window;
 }
 
diff --git a/engines/director/director.h b/engines/director/director.h
index d45752dc124..6a80c22d237 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -321,6 +321,8 @@ private:
 	StartOptions _options;
 
 public:
+	const Common::Array<Window *> *getWindowList() { return &_windowList; }
+
 	int _tickBaseline;
 	Common::Path _traceLogFile;
 
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 2cabda15c78..4884bd8afb4 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -701,4 +701,14 @@ uint32 Window::frozenLingoRecursionCount() {
 	return count;
 }
 
+Common::String Window::formatWindowInfo() {
+	return Common::String::format(
+			"name: \"%s\", movie: \"%s\", currentPath: \"%s\", dims: (%d,%d) %dx%d, innerDims: (%d, %d) %dx%d, visible: %d",
+			_name.c_str(), _currentMovie->getMacName().c_str(), _currentPath.c_str(),
+			_dims.left, _dims.top, _dims.width(), _dims.height(),
+			_innerDims.left, _innerDims.top, _innerDims.width(), _innerDims.height(),
+			_visible
+	);
+}
+
 } // End of namespace Director
diff --git a/engines/director/window.h b/engines/director/window.h
index 8a3e877d0ce..765f1289e9a 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -167,6 +167,8 @@ public:
 	bool thawLingoPlayState();
 	LingoState *getLastFrozenLingoState() { return _frozenLingoStates.empty() ? nullptr : _frozenLingoStates[_frozenLingoStates.size() - 1]; }
 
+	Common::String formatWindowInfo();
+
 	// events.cpp
 	bool processEvent(Common::Event &event) override;
 


Commit: 5f336ea4020c5c188e2dedd902e7ccda84dca949
    https://github.com/scummvm/scummvm/commit/5f336ea4020c5c188e2dedd902e7ccda84dca949
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: XOBJ: Add additional functions for HenryXObj

Changed paths:
    engines/director/lingo/xlibs/henry.cpp
    engines/director/lingo/xlibs/henry.h


diff --git a/engines/director/lingo/xlibs/henry.cpp b/engines/director/lingo/xlibs/henry.cpp
index 308991318c1..77e65aeec8e 100644
--- a/engines/director/lingo/xlibs/henry.cpp
+++ b/engines/director/lingo/xlibs/henry.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/file.h"
 #include "common/system.h"
 
 #include "director/director.h"
@@ -36,6 +37,7 @@
  **************************************************/
 
 /*
+-- From Mummy:
 -- Henry XObject. Mar 21, 95 JPY
 --Henry
 ISS    mNew                --Creates a new instance of the XObject
@@ -83,6 +85,48 @@ SS             mGetItemLocation --
 SS             mGetContainerContents --
 X              mPauseGame --
 X              mResumeGame --
+
+-- From Frankenstein
+-- Henry XObject. Mar 21, 95 JPY
+--Henry
+ISS    mNew                --Creates a new instance of the XObject
+X      mDispose            --Disposes of XObject instance
+S      mName
+SIII           mUserHitMouse                   --
+XSSS           mStartNewPosition                       --
+XSS            mStartNewPositionSubView --
+S                      mCommittNewPosition --
+S                      mDoLeftTurn                             --
+S              mDoRightTurn            --
+SII    mCheckCursor            --
+SII    mGetRollOverActions --
+S              mGetCurrentPosition             --
+S              mGetRoomList            --
+S              mGetVariableList                --
+SI             mGetItemList --
+S              mGetEntryActions        --
+S              mPeekEntryActions       --
+S              mGetExitActions         --
+SS             mGetTimerActionsForTimer --
+SS             mGetTimerStatus
+SSS    mSaveGameState          --
+SS             mLoadGameState          --
+IS             mGetStateVariable       --
+XSI    mSetStateVariable       --
+SS             mGetStringVariable      --
+XSS    mSetStringVariable      --
+XSI    mStartTimer             --
+XS             mAbortTimer             --
+S              mCheckTimers            --
+XS             mDropItem               --
+XS             mDumpItem
+XS             mPutItemInHand          --
+XS             mPutItemInEnvironment           --
+XS             mPutItemInBag           --
+SS             mGetItemLocation                --
+XI             mShowCursor             --
+X              mReleaseCursor          --
+
  */
 
 namespace Director {
@@ -108,7 +152,6 @@ static const MethodProto xlibMethods[] = {
 	{ "getEntryActions",				HenryXObj::m_getEntryActions,		 0, 0,	400 },
 	{ "peekEntryActions",				HenryXObj::m_peekEntryActions,		 0, 0,	400 },
 	{ "getExitActions",				HenryXObj::m_getExitActions,		 0, 0,	400 },
-	{ "setSavedPosition",				HenryXObj::m_setSavedPosition,		 0, 0,	400 },
 	{ "getStateVariable",				HenryXObj::m_getStateVariable,		 1, 1,	400 },
 	{ "setStateVariable",				HenryXObj::m_setStateVariable,		 2, 2,	400 },
 	{ "getStringVariable",				HenryXObj::m_getStringVariable,		 1, 1,	400 },
@@ -117,28 +160,41 @@ static const MethodProto xlibMethods[] = {
 	{ "abortTimer",				HenryXObj::m_abortTimer,		 1, 1,	400 },
 	{ "checkTimers",				HenryXObj::m_checkTimers,		 0, 0,	400 },
 	{ "getTimerStatus",				HenryXObj::m_getTimerStatus,		 1, 1,	400 },
-	{ "pickUpItem",				HenryXObj::m_pickUpItem,		 1, 1,	400 },
 	{ "dropItem",				HenryXObj::m_dropItem,		 1, 1,	400 },
 	{ "dumpItem",				HenryXObj::m_dumpItem,		 1, 1,	400 },
+	{ "getCurrentPosition",				HenryXObj::m_getCurrentPosition,		 0, 0,	400 },
+	{ "showCursor",				HenryXObj::m_showCursor,		 1, 1,	400 },
+	{ "releaseCursor",				HenryXObj::m_releaseCursor,		 0, 0,	400 },
+	{ "getRoomList",				HenryXObj::m_getRoomList,		 0, 0,	400 },
+	{ "getItemList",				HenryXObj::m_getItemList,		 1, 1,	400 },
+	{ "getItemLocation",				HenryXObj::m_getItemLocation,		 1, 1,	400 },
+
+	// Functions for Mummy
+	{ "setSavedPosition",				HenryXObj::m_setSavedPosition,		 0, 0,	400 },
+	{ "pickUpItem",				HenryXObj::m_pickUpItem,		 1, 1,	400 },
 	{ "returnItem",				HenryXObj::m_returnItem,		 1, 1,	400 },
 	{ "ingestItem",				HenryXObj::m_ingestItem,		 1, 1,	400 },
 	{ "putItemInContainer",				HenryXObj::m_putItemInContainer,		 2, 2,	400 },
 	{ "putItemAtLocation",				HenryXObj::m_putItemAtLocation,		 4, 4,	400 },
-	{ "getCurrentPosition",				HenryXObj::m_getCurrentPosition,		 0, 0,	400 },
 	{ "getPlayerProperties",				HenryXObj::m_getPlayerProperties,		 0, 0,	400 },
 	{ "saveGame",				HenryXObj::m_saveGame,		 2, 2,	400 },
 	{ "loadGame",				HenryXObj::m_loadGame,		 1, 1,	400 },
-	{ "showCursor",				HenryXObj::m_showCursor,		 1, 1,	400 },
-	{ "releaseCursor",				HenryXObj::m_releaseCursor,		 0, 0,	400 },
-	{ "getRoomList",				HenryXObj::m_getRoomList,		 0, 0,	400 },
-	{ "getItemList",				HenryXObj::m_getItemList,		 1, 1,	400 },
 	{ "getCurrentItem",				HenryXObj::m_getCurrentItem,		 0, 0,	400 },
 	{ "getCurrentContainer",				HenryXObj::m_getCurrentContainer,		 0, 0,	400 },
 	{ "getCurrentInteraction",				HenryXObj::m_getCurrentInteraction,		 0, 0,	400 },
-	{ "getItemLocation",				HenryXObj::m_getItemLocation,		 1, 1,	400 },
 	{ "getContainerContents",				HenryXObj::m_getContainerContents,		 1, 1,	400 },
 	{ "pauseGame",				HenryXObj::m_pauseGame,		 0, 0,	400 },
 	{ "resumeGame",				HenryXObj::m_resumeGame,		 0, 0,	400 },
+
+	// Functions for Frankenstein
+	{ "putItemInHand",				HenryXObj::m_putItemInHand,				1, 1,	400 },
+	{ "putItemInEnvironment",		HenryXObj::m_putItemInEnvironment,		1, 1,	400 },
+	{ "putItemInBag",				HenryXObj::m_putItemInBag,				1, 1,	400 },
+	{ "getVariableList",			HenryXObj::m_getVariableList,           0, 0,	400 },
+	{ "getTimerActionsForTimer",	HenryXObj::m_getTimerActionsForTimer,   1, 1,	400 },
+	{ "saveGameState",				HenryXObj::m_saveGameState,				2, 2,	400 },
+	{ "loadGameState",				HenryXObj::m_loadGameState,				1, 1,	400 },
+
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
@@ -147,6 +203,23 @@ static const BuiltinProto xlibBuiltins[] = {
 	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
 };
 
+
+bool CheckKey(Common::File &file) {
+	return file.readUint32BE() == 4;
+}
+
+void GameState_Read() {
+	Common::File gameStateFile;
+	if (!CheckKey(gameStateFile)) {
+		// invalid file
+		gameStateFile.close();
+
+	} else {
+
+	}
+}
+
+
 HenryXObject::HenryXObject(ObjectType ObjectType) :Object<HenryXObject>("Henry") {
 	_objType = ObjectType;
 }
@@ -185,7 +258,6 @@ XOBJSTUB(HenryXObj::m_getRollOverActions, "")
 XOBJSTUB(HenryXObj::m_getEntryActions, "")
 XOBJSTUB(HenryXObj::m_peekEntryActions, "")
 XOBJSTUB(HenryXObj::m_getExitActions, "")
-XOBJSTUB(HenryXObj::m_setSavedPosition, "")
 XOBJSTUB(HenryXObj::m_getStateVariable, 0)
 XOBJSTUBNR(HenryXObj::m_setStateVariable)
 XOBJSTUB(HenryXObj::m_getStringVariable, "")
@@ -194,27 +266,37 @@ XOBJSTUBNR(HenryXObj::m_startTimer)
 XOBJSTUBNR(HenryXObj::m_abortTimer)
 XOBJSTUB(HenryXObj::m_checkTimers, "")
 XOBJSTUB(HenryXObj::m_getTimerStatus, "")
-XOBJSTUB(HenryXObj::m_pickUpItem, "")
 XOBJSTUBNR(HenryXObj::m_dropItem)
 XOBJSTUBNR(HenryXObj::m_dumpItem)
+XOBJSTUB(HenryXObj::m_getCurrentPosition, "")
+XOBJSTUBNR(HenryXObj::m_showCursor)
+XOBJSTUBNR(HenryXObj::m_releaseCursor)
+XOBJSTUB(HenryXObj::m_getRoomList, "")
+XOBJSTUB(HenryXObj::m_getItemList, "")
+XOBJSTUB(HenryXObj::m_getItemLocation, "")
+
+XOBJSTUB(HenryXObj::m_setSavedPosition, "")
+XOBJSTUB(HenryXObj::m_pickUpItem, "")
 XOBJSTUB(HenryXObj::m_returnItem, "")
 XOBJSTUB(HenryXObj::m_ingestItem, "")
 XOBJSTUB(HenryXObj::m_putItemInContainer, "")
 XOBJSTUB(HenryXObj::m_putItemAtLocation, "")
-XOBJSTUB(HenryXObj::m_getCurrentPosition, "")
 XOBJSTUB(HenryXObj::m_getPlayerProperties, "")
 XOBJSTUB(HenryXObj::m_saveGame, "")
 XOBJSTUB(HenryXObj::m_loadGame, "")
-XOBJSTUBNR(HenryXObj::m_showCursor)
-XOBJSTUBNR(HenryXObj::m_releaseCursor)
-XOBJSTUB(HenryXObj::m_getRoomList, "")
-XOBJSTUB(HenryXObj::m_getItemList, "")
 XOBJSTUB(HenryXObj::m_getCurrentItem, "")
 XOBJSTUB(HenryXObj::m_getCurrentContainer, "")
 XOBJSTUB(HenryXObj::m_getCurrentInteraction, "")
-XOBJSTUB(HenryXObj::m_getItemLocation, "")
 XOBJSTUB(HenryXObj::m_getContainerContents, "")
 XOBJSTUBNR(HenryXObj::m_pauseGame)
 XOBJSTUBNR(HenryXObj::m_resumeGame)
 
+XOBJSTUBNR(HenryXObj::m_putItemInHand)
+XOBJSTUBNR(HenryXObj::m_putItemInEnvironment)
+XOBJSTUBNR(HenryXObj::m_putItemInBag)
+XOBJSTUB(HenryXObj::m_getVariableList, "")
+XOBJSTUB(HenryXObj::m_getTimerActionsForTimer, "")
+XOBJSTUB(HenryXObj::m_saveGameState, "")
+XOBJSTUB(HenryXObj::m_loadGameState, "")
+
 }
diff --git a/engines/director/lingo/xlibs/henry.h b/engines/director/lingo/xlibs/henry.h
index 1863c9ddafe..2ef9918f60c 100644
--- a/engines/director/lingo/xlibs/henry.h
+++ b/engines/director/lingo/xlibs/henry.h
@@ -51,7 +51,6 @@ void m_getRollOverActions(int nargs);
 void m_getEntryActions(int nargs);
 void m_peekEntryActions(int nargs);
 void m_getExitActions(int nargs);
-void m_setSavedPosition(int nargs);
 void m_getStateVariable(int nargs);
 void m_setStateVariable(int nargs);
 void m_getStringVariable(int nargs);
@@ -60,29 +59,40 @@ void m_startTimer(int nargs);
 void m_abortTimer(int nargs);
 void m_checkTimers(int nargs);
 void m_getTimerStatus(int nargs);
-void m_pickUpItem(int nargs);
 void m_dropItem(int nargs);
 void m_dumpItem(int nargs);
+void m_getCurrentPosition(int nargs);
+void m_showCursor(int nargs);
+void m_releaseCursor(int nargs);
+void m_getRoomList(int nargs);
+void m_getItemList(int nargs);
+void m_getItemLocation(int nargs);
+
+void m_setSavedPosition(int nargs);
+void m_pickUpItem(int nargs);
 void m_returnItem(int nargs);
 void m_ingestItem(int nargs);
 void m_putItemInContainer(int nargs);
 void m_putItemAtLocation(int nargs);
-void m_getCurrentPosition(int nargs);
 void m_getPlayerProperties(int nargs);
 void m_saveGame(int nargs);
 void m_loadGame(int nargs);
-void m_showCursor(int nargs);
-void m_releaseCursor(int nargs);
-void m_getRoomList(int nargs);
-void m_getItemList(int nargs);
 void m_getCurrentItem(int nargs);
 void m_getCurrentContainer(int nargs);
 void m_getCurrentInteraction(int nargs);
-void m_getItemLocation(int nargs);
 void m_getContainerContents(int nargs);
 void m_pauseGame(int nargs);
 void m_resumeGame(int nargs);
 
+void m_putItemInHand(int nargs);
+void m_putItemInEnvironment(int nargs);
+void m_putItemInBag(int nargs);
+void m_getVariableList(int nargs);
+void m_getTimerActionsForTimer(int nargs);
+void m_saveGameState(int nargs);
+void m_loadGameState(int nargs);
+
+
 } // End of namespace HenryXObj
 
 } // End of namespace Director


Commit: 151d52f938ac277042286bf2f44daf1da6edeabb
    https://github.com/scummvm/scummvm/commit/151d52f938ac277042286bf2f44daf1da6edeabb
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Move Lingo stack into LingoState, fix c_tell infinite loops

Fixes crashes when starting a new game in Zeddas: Servant of Sheol.

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/score.cpp
    engines/director/score.h
    engines/director/window.cpp
    engines/director/window.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 4b38569ea27..814c3f031fb 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -318,7 +318,7 @@ void Lingo::printArgs(const char *funcname, int nargs, const char *prefix) {
 	s += '(';
 
 	for (int i = 0; i < nargs; i++) {
-		Datum d = _stack[_stack.size() - nargs + i];
+		Datum d = _state->stack[_state->stack.size() - nargs + i];
 
 		s += d.asString(true);
 
@@ -332,9 +332,9 @@ void Lingo::printArgs(const char *funcname, int nargs, const char *prefix) {
 }
 
 void Lingo::convertVOIDtoString(int arg, int nargs) {
-	if (_stack[_stack.size() - nargs + arg].type == VOID) {
-		if (_stack[_stack.size() - nargs + arg].u.s != nullptr)
-			g_lingo->_stack[_stack.size() - nargs + arg].type = STRING;
+	if (_state->stack[_state->stack.size() - nargs + arg].type == VOID) {
+		if (_state->stack[_state->stack.size() - nargs + arg].u.s != nullptr)
+			g_lingo->_state->stack[_state->stack.size() - nargs + arg].type = STRING;
 		else
 			warning("Incorrect convertVOIDtoString for arg %d of %d", arg, nargs);
 	}
@@ -346,11 +346,11 @@ void Lingo::dropStack(int nargs) {
 }
 
 void Lingo::drop(uint num) {
-	if (num > _stack.size() - 1) {
-		warning("Incorrect number of elements to drop from stack: %d > %d", num, _stack.size() - 1);
+	if (num > _state->stack.size() - 1) {
+		warning("Incorrect number of elements to drop from stack: %d > %d", num, _state->stack.size() - 1);
 		return;
 	}
-	_stack.remove_at(_stack.size() - 1 - num);
+	_state->stack.remove_at(_state->stack.size() - 1 - num);
 }
 
 
@@ -1073,7 +1073,7 @@ void LB::b_max(int nargs) {
 		}
 	} else if (nargs > 0) {
 		for (int i = 0; i < nargs; i++) {
-			Datum d = g_lingo->_stack[g_lingo->_stack.size() - nargs + i];
+			Datum d = g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs + i];
 			if (d.type == ARRAY) {
 				warning("b_max: undefined behavior: array mixed with other args");
 			}
@@ -1106,7 +1106,7 @@ void LB::b_min(int nargs) {
 		}
 	} else if (nargs > 0) {
 		for (int i = 0; i < nargs; i++) {
-			Datum d = g_lingo->_stack[g_lingo->_stack.size() - nargs + i];
+			Datum d = g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs + i];
 			if (d.type == ARRAY) {
 				warning("b_min: undefined behavior: array mixed with other args");
 			}
@@ -1882,7 +1882,7 @@ void LB::b_return(int nargs) {
 	}
 
 	// clear any temp values from loops
-	while (g_lingo->_stack.size() > fp->stackSizeBefore)
+	while (g_lingo->_state->stack.size() > fp->stackSizeBefore)
 		g_lingo->pop();
 
 	// Do not allow a factory's mNew method to return a value
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index 76a9a1936fc..e8bdba3a7ea 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -462,7 +462,7 @@ void LC::cb_objectcall() {
 	}
 
 	if (nargs.u.i > 0) {
-		Datum &firstArg = g_lingo->_stack[g_lingo->_stack.size() - nargs.u.i];
+		Datum &firstArg = g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs.u.i];
 		// The first arg could be either a method name or a variable name
 		if (firstArg.type == SYMBOL) {
 			firstArg.type = VARREF;
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index b6021f024cd..e74194f79b9 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -185,7 +185,7 @@ void Lingo::cleanupFuncs() {
 }
 
 void Lingo::push(Datum d) {
-	_stack.push_back(d);
+	_state->stack.push_back(d);
 }
 
 Datum Lingo::getVoid() {
@@ -201,18 +201,18 @@ void Lingo::pushVoid() {
 }
 
 Datum Lingo::pop() {
-	assert (_stack.size() != 0);
+	assert (_state->stack.size() != 0);
 
-	Datum ret = _stack.back();
-	_stack.pop_back();
+	Datum ret = _state->stack.back();
+	_state->stack.pop_back();
 
 	return ret;
 }
 
 Datum Lingo::peek(uint offset) {
-	assert (_stack.size() > offset);
+	assert (_state->stack.size() > offset);
 
-	Datum ret = _stack[_stack.size() - 1 - offset];
+	Datum ret = _state->stack[_state->stack.size() - 1 - offset];
 
 	return ret;
 }
@@ -296,7 +296,7 @@ void Lingo::pushContext(const Symbol funcSym, bool allowRetVal, Datum defaultRet
 	}
 	_state->localVars = localvars;
 
-	fp->stackSizeBefore = _stack.size();
+	fp->stackSizeBefore = _state->stack.size();
 
 	callstack.push_back(fp);
 
@@ -314,12 +314,12 @@ void Lingo::popContext(bool aborting) {
 	CFrame *fp = callstack.back();
 	callstack.pop_back();
 
-	if (_stack.size() == fp->stackSizeBefore + 1) {
+	if (_state->stack.size() == fp->stackSizeBefore + 1) {
 		if (!fp->allowRetVal) {
 			debugC(5, kDebugLingoExec, "dropping return value");
 			pop();
 		}
-	} else if (_stack.size() == fp->stackSizeBefore) {
+	} else if (_state->stack.size() == fp->stackSizeBefore) {
 		if (fp->allowRetVal) {
 			// Don't warn about missing return value if there's an explicit, non-VOID default,
 			// e.g. for factories' mNew method.
@@ -328,18 +328,18 @@ void Lingo::popContext(bool aborting) {
 			}
 			push(fp->defaultRetVal);
 		}
-	} else if (_stack.size() > fp->stackSizeBefore) {
+	} else if (_state->stack.size() > fp->stackSizeBefore) {
 		if (aborting) {
 			// Since we're aborting execution, we should expect that some extra
 			// values are left on the stack.
-			while (_stack.size() > fp->stackSizeBefore) {
+			while (_state->stack.size() > fp->stackSizeBefore) {
 				pop();
 			}
 		} else {
-			error("handler %s returned extra %d values", fp->sp.name->c_str(), _stack.size() - fp->stackSizeBefore);
+			error("handler %s returned extra %d values", fp->sp.name->c_str(), _state->stack.size() - fp->stackSizeBefore);
 		}
 	} else {
-		error("handler %s popped extra %d values", fp->sp.name->c_str(), fp->stackSizeBefore - _stack.size());
+		error("handler %s popped extra %d values", fp->sp.name->c_str(), fp->stackSizeBefore - _state->stack.size());
 	}
 
 	_state->context->decRefCount();
@@ -1504,28 +1504,35 @@ void LC::c_whencode() {
 void LC::c_tell() {
 	// swap out current window
 	Datum window = g_lingo->pop();
-	g_lingo->push(g_director->getCurrentWindow());
+	Window *currentWindow = g_director->getCurrentWindow();
+	g_lingo->push(currentWindow);
 	if (window.type != OBJECT || window.u.obj->getObjType() != kWindowObj) {
 		warning("LC::c_tell(): wrong argument type: %s", window.type2str());
 		return;
 	}
 	Window *w = static_cast<Window *>(window.u.obj);
-	w->ensureMovieIsLoaded();
-	if (w->getCurrentMovie() == nullptr) {
-		warning("LC::c_tell(): window has no movie");
-		return;
+	if (currentWindow != w) {
+		w->ensureMovieIsLoaded();
+		if (w->getCurrentMovie() == nullptr) {
+			warning("LC::c_tell(): window has no movie");
+			return;
+		}
 	}
+	currentWindow->moveLingoState(w);
 	g_director->setCurrentWindow(w);
 
 }
 
 void LC::c_telldone() {
 	Datum returnWindow = g_lingo->pop();
+	Window *currentWindow = g_director->getCurrentWindow();
 	if (returnWindow.type != OBJECT || returnWindow.u.obj->getObjType() != kWindowObj) {
 		warning("LC::c_telldone(): wrong return window type: %s", returnWindow.type2str());
 		return;
 	}
-	g_director->setCurrentWindow(static_cast<Window *>(returnWindow.u.obj));
+	Window *w = static_cast<Window *>(returnWindow.u.obj);
+	currentWindow->moveLingoState(w);
+	g_director->setCurrentWindow(w);
 }
 
 
@@ -1556,7 +1563,7 @@ void LC::call(const Common::String &name, int nargs, bool allowRetVal) {
 	Symbol funcSym;
 
 	if (nargs > 0) {
-		Datum firstArg = g_lingo->_stack[g_lingo->_stack.size() - nargs];
+		Datum firstArg = g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs];
 
 		// Factory/XObject method call
 		if (firstArg.isVarRef()) { // first arg could be method name
@@ -1571,14 +1578,14 @@ void LC::call(const Common::String &name, int nargs, bool allowRetVal) {
 				}
 				funcSym = target->getMethod(*firstArg.u.s);
 				if (funcSym.type != VOIDSYM) {
-					g_lingo->_stack[g_lingo->_stack.size() - nargs] = funcSym.target; // Set first arg to target
+					g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs] = funcSym.target; // Set first arg to target
 					call(funcSym, nargs, allowRetVal);
 				} else {
 					g_lingo->lingoError("Object <%s> has no method '%s'", obj.asString(true).c_str(), firstArg.u.s->c_str());
 				}
 				return;
 			}
-			firstArg = g_lingo->_stack[g_lingo->_stack.size() - nargs] = firstArg.eval();
+			firstArg = g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs] = firstArg.eval();
 		}
 
 		// Script/Xtra method call
@@ -1590,7 +1597,7 @@ void LC::call(const Common::String &name, int nargs, bool allowRetVal) {
 			}
 			funcSym = target->getMethod(name);
 			if (funcSym.type != VOIDSYM) {
-				g_lingo->_stack[g_lingo->_stack.size() - nargs] = target; // Set first arg to target
+				g_lingo->_state->stack[g_lingo->_state->stack.size() - nargs] = target; // Set first arg to target
 				call(funcSym, nargs, allowRetVal);
 				return;
 			}
@@ -1689,7 +1696,7 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
 
 	if (funcSym.type != HANDLER && target.type != VOID) {
 		// Drop the target argument (only needed for user-defined methods)
-		g_lingo->_stack.remove_at(g_lingo->_stack.size() - nargs);
+		g_lingo->_state->stack.remove_at(g_lingo->_state->stack.size() - nargs);
 		nargs--;
 	}
 
@@ -1725,7 +1732,7 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
 
 	if (funcSym.type != HANDLER) {
 		g_debugger->builtinHook(funcSym);
-		uint stackSizeBefore = g_lingo->_stack.size() - nargs;
+		uint stackSizeBefore = g_lingo->_state->stack.size() - nargs;
 
 		if (target.type != VOID) {
 			// Only need to update the me obj
@@ -1743,7 +1750,7 @@ void LC::call(const Symbol &funcSym, int nargs, bool allowRetVal) {
 			(*funcSym.u.bltin)(nargs);
 		}
 
-		uint stackSize = g_lingo->_stack.size();
+		uint stackSize = g_lingo->_state->stack.size();
 
 		if (funcSym.u.bltin != LB::b_return && funcSym.u.bltin != LB::b_value) {
 			if (stackSize == stackSizeBefore + 1) {
@@ -1787,7 +1794,7 @@ void LC::c_procret() {
 	// Returning a value must be done by calling LB::b_return().
 	Common::Array<CFrame *> &callstack = g_lingo->_state->callstack;
 	CFrame *fp = callstack.back();
-	int extra = g_lingo->_stack.size() - fp->stackSizeBefore;
+	int extra = g_lingo->_state->stack.size() - fp->stackSizeBefore;
 	if (extra > 0) {
 		debugC(5, kDebugLingoExec, "c_procret: dropping %d items", extra);
 		g_lingo->dropStack(extra);
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 6ada42159d1..793fd8c0c0b 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -630,10 +630,10 @@ void LM::m_perform(int nargs) {
 	// mNew is called with mPerform
 	Datum d(g_lingo->_state->me);
 	AbstractObject *me = d.u.obj;
-	Datum methodName = g_lingo->_stack.remove_at(g_lingo->_stack.size() - nargs); // Take method name out of stack
+	Datum methodName = g_lingo->_state->stack.remove_at(g_lingo->_state->stack.size() - nargs); // Take method name out of stack
 	Symbol funcSym = me->getMethod(*methodName.u.s);
 	// Object methods expect the first argument to be the object
-	g_lingo->_stack.insert_at(g_lingo->_stack.size() - nargs + 1, d);
+	g_lingo->_state->stack.insert_at(g_lingo->_state->stack.size() - nargs + 1, d);
 	LC::call(funcSym, nargs, allowRetVal);
 
 	if (allowRetVal) {
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index e38d6d8625e..9f25f147800 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -416,8 +416,8 @@ void LingoArchive::replaceCode(const Common::U32String &code, ScriptType type, u
 Common::String Lingo::formatStack() {
 	Common::String stack;
 
-	for (uint i = 0; i < _stack.size(); i++) {
-		Datum d = _stack[i];
+	for (uint i = 0; i < _state->stack.size(); i++) {
+		Datum d = _state->stack[i];
 		stack += Common::String::format("<%s> ", d.asString(true).c_str());
 	}
 	return stack;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 8357c8d18eb..9b00c66a7a9 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -335,6 +335,7 @@ struct LingoState {
 	ScriptContext *context = nullptr;		// current Lingo script context
 	DatumHash *localVars = nullptr;			// current local variables
 	Datum me;								// current me object
+	StackData stack;
 
 	~LingoState();
 };
@@ -547,8 +548,6 @@ public:
 
 	uint _globalCounter;
 
-	StackData _stack;
-
 	DirectorEngine *_vm;
 
 	int _floatPrecision;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 79963aacf5e..5b1e9a70cc7 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -82,6 +82,7 @@ Score::Score(Movie *movie) {
 	_waitForClickCursor = false;
 	_activeFade = false;
 	_exitFrameCalled = false;
+	_stopPlayCalled = false;
 	_playState = kPlayNotStarted;
 
 	_numChannelsDisplayed = 0;
@@ -353,6 +354,9 @@ void Score::step() {
 }
 
 void Score::stopPlay() {
+	if (_stopPlayCalled)
+		return;
+	_stopPlayCalled = true;
 	if (_vm->getVersion() >= 300)
 		_movie->processEvent(kEventStopMovie);
 	_lingo->executePerFrameHook(-1, 0);
diff --git a/engines/director/score.h b/engines/director/score.h
index 5f0117d5246..6cd1e551d7d 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -187,6 +187,7 @@ public:
 	bool _cursorDirty;
 	bool _activeFade;
 	bool _exitFrameCalled;
+	bool _stopPlayCalled;
 	Cursor _defaultCursor;
 	CursorRef _currentCursor;
 	bool _skipTransition;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 4884bd8afb4..9cb4387767a 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -366,6 +366,12 @@ void Window::ensureMovieIsLoaded() {
 		return;
 	}
 
+	if (_currentMovie) {
+		if (!_lingoState->callstack.empty())
+			freezeLingoState();
+		_currentMovie->getScore()->stopPlay();
+	}
+
 	loadNextMovie();
 
 	if (_currentMovie->getScore()->_playState == kPlayNotStarted)
@@ -673,6 +679,17 @@ bool Window::thawLingoPlayState() {
 }
 
 
+void Window::moveLingoState(Window *target) {
+	if (target == this)
+		return;
+	if (!target->_lingoState->callstack.empty())
+		target->freezeLingoState();
+	delete target->_lingoState;
+	target->_lingoState = _lingoState;
+	_lingoState = new LingoState();
+}
+
+
 // Check how many times enterFrame/stepMovie have been called recursively.
 // When Lingo encounters a go() call, it freezes the execution state and starts
 // processing the next frame. In the case of enterFrame/stepMovie, it is possible
diff --git a/engines/director/window.h b/engines/director/window.h
index 765f1289e9a..fce9be0a3b0 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -166,6 +166,7 @@ public:
 	void freezeLingoPlayState();
 	bool thawLingoPlayState();
 	LingoState *getLastFrozenLingoState() { return _frozenLingoStates.empty() ? nullptr : _frozenLingoStates[_frozenLingoStates.size() - 1]; }
+	void moveLingoState(Window *target);
 
 	Common::String formatWindowInfo();
 


Commit: a78f0285d2313c4160168f1e0ab3e078a2a610c9
    https://github.com/scummvm/scummvm/commit/a78f0285d2313c4160168f1e0ab3e078a2a610c9
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Director 5 Lingo parser additions

Changed paths:
    engines/director/lingo/lingo-gr.cpp
    engines/director/lingo/lingo-gr.h
    engines/director/lingo/lingo-gr.y
    engines/director/lingo/lingo-lex.cpp
    engines/director/lingo/lingo-lex.l


diff --git a/engines/director/lingo/lingo-gr.cpp b/engines/director/lingo/lingo-gr.cpp
index be28814fd0a..29bb3c2de12 100644
--- a/engines/director/lingo/lingo-gr.cpp
+++ b/engines/director/lingo/lingo-gr.cpp
@@ -174,163 +174,165 @@ enum yysymbol_kind_t
   YYSYMBOL_tFIELD = 11,                    /* tFIELD  */
   YYSYMBOL_tSCRIPT = 12,                   /* tSCRIPT  */
   YYSYMBOL_tWINDOW = 13,                   /* tWINDOW  */
-  YYSYMBOL_tDELETE = 14,                   /* tDELETE  */
-  YYSYMBOL_tDOWN = 15,                     /* tDOWN  */
-  YYSYMBOL_tELSE = 16,                     /* tELSE  */
-  YYSYMBOL_tEXIT = 17,                     /* tEXIT  */
-  YYSYMBOL_tFRAME = 18,                    /* tFRAME  */
-  YYSYMBOL_tGLOBAL = 19,                   /* tGLOBAL  */
-  YYSYMBOL_tGO = 20,                       /* tGO  */
-  YYSYMBOL_tHILITE = 21,                   /* tHILITE  */
-  YYSYMBOL_tIF = 22,                       /* tIF  */
-  YYSYMBOL_tIN = 23,                       /* tIN  */
-  YYSYMBOL_tINTO = 24,                     /* tINTO  */
-  YYSYMBOL_tMACRO = 25,                    /* tMACRO  */
-  YYSYMBOL_tRETURN = 26,                   /* tRETURN  */
-  YYSYMBOL_tMOVIE = 27,                    /* tMOVIE  */
-  YYSYMBOL_tNEXT = 28,                     /* tNEXT  */
-  YYSYMBOL_tOF = 29,                       /* tOF  */
-  YYSYMBOL_tPREVIOUS = 30,                 /* tPREVIOUS  */
-  YYSYMBOL_tPUT = 31,                      /* tPUT  */
-  YYSYMBOL_tREPEAT = 32,                   /* tREPEAT  */
-  YYSYMBOL_tSET = 33,                      /* tSET  */
-  YYSYMBOL_tTHEN = 34,                     /* tTHEN  */
-  YYSYMBOL_tTO = 35,                       /* tTO  */
-  YYSYMBOL_tWHEN = 36,                     /* tWHEN  */
-  YYSYMBOL_tWITH = 37,                     /* tWITH  */
-  YYSYMBOL_tWHILE = 38,                    /* tWHILE  */
-  YYSYMBOL_tFACTORY = 39,                  /* tFACTORY  */
-  YYSYMBOL_tOPEN = 40,                     /* tOPEN  */
-  YYSYMBOL_tPLAY = 41,                     /* tPLAY  */
-  YYSYMBOL_tINSTANCE = 42,                 /* tINSTANCE  */
-  YYSYMBOL_tGE = 43,                       /* tGE  */
-  YYSYMBOL_tLE = 44,                       /* tLE  */
-  YYSYMBOL_tEQ = 45,                       /* tEQ  */
-  YYSYMBOL_tNEQ = 46,                      /* tNEQ  */
-  YYSYMBOL_tAND = 47,                      /* tAND  */
-  YYSYMBOL_tOR = 48,                       /* tOR  */
-  YYSYMBOL_tNOT = 49,                      /* tNOT  */
-  YYSYMBOL_tMOD = 50,                      /* tMOD  */
-  YYSYMBOL_tAFTER = 51,                    /* tAFTER  */
-  YYSYMBOL_tBEFORE = 52,                   /* tBEFORE  */
-  YYSYMBOL_tCONCAT = 53,                   /* tCONCAT  */
-  YYSYMBOL_tCONTAINS = 54,                 /* tCONTAINS  */
-  YYSYMBOL_tSTARTS = 55,                   /* tSTARTS  */
-  YYSYMBOL_tCHAR = 56,                     /* tCHAR  */
-  YYSYMBOL_tCHARS = 57,                    /* tCHARS  */
-  YYSYMBOL_tITEM = 58,                     /* tITEM  */
-  YYSYMBOL_tITEMS = 59,                    /* tITEMS  */
-  YYSYMBOL_tLINE = 60,                     /* tLINE  */
-  YYSYMBOL_tLINES = 61,                    /* tLINES  */
-  YYSYMBOL_tWORD = 62,                     /* tWORD  */
-  YYSYMBOL_tWORDS = 63,                    /* tWORDS  */
-  YYSYMBOL_tABBREVIATED = 64,              /* tABBREVIATED  */
-  YYSYMBOL_tABBREV = 65,                   /* tABBREV  */
-  YYSYMBOL_tABBR = 66,                     /* tABBR  */
-  YYSYMBOL_tLONG = 67,                     /* tLONG  */
-  YYSYMBOL_tSHORT = 68,                    /* tSHORT  */
-  YYSYMBOL_tDATE = 69,                     /* tDATE  */
-  YYSYMBOL_tLAST = 70,                     /* tLAST  */
-  YYSYMBOL_tMENU = 71,                     /* tMENU  */
-  YYSYMBOL_tMENUS = 72,                    /* tMENUS  */
-  YYSYMBOL_tMENUITEM = 73,                 /* tMENUITEM  */
-  YYSYMBOL_tMENUITEMS = 74,                /* tMENUITEMS  */
-  YYSYMBOL_tNUMBER = 75,                   /* tNUMBER  */
-  YYSYMBOL_tTHE = 76,                      /* tTHE  */
-  YYSYMBOL_tTIME = 77,                     /* tTIME  */
-  YYSYMBOL_tXTRAS = 78,                    /* tXTRAS  */
-  YYSYMBOL_tCASTLIBS = 79,                 /* tCASTLIBS  */
-  YYSYMBOL_tSOUND = 80,                    /* tSOUND  */
-  YYSYMBOL_tSPRITE = 81,                   /* tSPRITE  */
-  YYSYMBOL_tINTERSECTS = 82,               /* tINTERSECTS  */
-  YYSYMBOL_tWITHIN = 83,                   /* tWITHIN  */
-  YYSYMBOL_tTELL = 84,                     /* tTELL  */
-  YYSYMBOL_tPROPERTY = 85,                 /* tPROPERTY  */
-  YYSYMBOL_tON = 86,                       /* tON  */
-  YYSYMBOL_tMETHOD = 87,                   /* tMETHOD  */
-  YYSYMBOL_tENDIF = 88,                    /* tENDIF  */
-  YYSYMBOL_tENDREPEAT = 89,                /* tENDREPEAT  */
-  YYSYMBOL_tENDTELL = 90,                  /* tENDTELL  */
-  YYSYMBOL_tASSERTERROR = 91,              /* tASSERTERROR  */
-  YYSYMBOL_92_ = 92,                       /* '<'  */
-  YYSYMBOL_93_ = 93,                       /* '>'  */
-  YYSYMBOL_94_ = 94,                       /* '&'  */
-  YYSYMBOL_95_ = 95,                       /* '+'  */
-  YYSYMBOL_96_ = 96,                       /* '-'  */
-  YYSYMBOL_97_ = 97,                       /* '*'  */
-  YYSYMBOL_98_ = 98,                       /* '/'  */
-  YYSYMBOL_99_n_ = 99,                     /* '\n'  */
-  YYSYMBOL_100_ = 100,                     /* ','  */
-  YYSYMBOL_101_ = 101,                     /* '('  */
-  YYSYMBOL_102_ = 102,                     /* ')'  */
-  YYSYMBOL_103_ = 103,                     /* '['  */
-  YYSYMBOL_104_ = 104,                     /* ']'  */
-  YYSYMBOL_105_ = 105,                     /* ':'  */
-  YYSYMBOL_YYACCEPT = 106,                 /* $accept  */
-  YYSYMBOL_script = 107,                   /* script  */
-  YYSYMBOL_scriptpartlist = 108,           /* scriptpartlist  */
-  YYSYMBOL_scriptpart = 109,               /* scriptpart  */
-  YYSYMBOL_macro = 110,                    /* macro  */
-  YYSYMBOL_factory = 111,                  /* factory  */
-  YYSYMBOL_method = 112,                   /* method  */
-  YYSYMBOL_methodlist = 113,               /* methodlist  */
-  YYSYMBOL_nonemptymethodlist = 114,       /* nonemptymethodlist  */
-  YYSYMBOL_methodlistline = 115,           /* methodlistline  */
-  YYSYMBOL_handler = 116,                  /* handler  */
-  YYSYMBOL_endargdef = 117,                /* endargdef  */
-  YYSYMBOL_CMDID = 118,                    /* CMDID  */
-  YYSYMBOL_ID = 119,                       /* ID  */
-  YYSYMBOL_idlist = 120,                   /* idlist  */
-  YYSYMBOL_nonemptyidlist = 121,           /* nonemptyidlist  */
-  YYSYMBOL_stmt = 122,                     /* stmt  */
-  YYSYMBOL_stmt_insideif = 123,            /* stmt_insideif  */
-  YYSYMBOL_stmtoneliner = 124,             /* stmtoneliner  */
-  YYSYMBOL_proc = 125,                     /* proc  */
-  YYSYMBOL_cmdargs = 126,                  /* cmdargs  */
-  YYSYMBOL_trailingcomma = 127,            /* trailingcomma  */
-  YYSYMBOL_frameargs = 128,                /* frameargs  */
-  YYSYMBOL_asgn = 129,                     /* asgn  */
-  YYSYMBOL_to = 130,                       /* to  */
-  YYSYMBOL_definevars = 131,               /* definevars  */
-  YYSYMBOL_ifstmt = 132,                   /* ifstmt  */
-  YYSYMBOL_ifelsestmt = 133,               /* ifelsestmt  */
-  YYSYMBOL_endif = 134,                    /* endif  */
-  YYSYMBOL_loop = 135,                     /* loop  */
-  YYSYMBOL_tell = 136,                     /* tell  */
-  YYSYMBOL_when = 137,                     /* when  */
-  YYSYMBOL_stmtlist = 138,                 /* stmtlist  */
-  YYSYMBOL_nonemptystmtlist = 139,         /* nonemptystmtlist  */
-  YYSYMBOL_stmtlistline = 140,             /* stmtlistline  */
-  YYSYMBOL_stmtlist_insideif = 141,        /* stmtlist_insideif  */
-  YYSYMBOL_nonemptystmtlist_insideif = 142, /* nonemptystmtlist_insideif  */
-  YYSYMBOL_stmtlistline_insideif = 143,    /* stmtlistline_insideif  */
-  YYSYMBOL_simpleexpr_nounarymath = 144,   /* simpleexpr_nounarymath  */
-  YYSYMBOL_var = 145,                      /* var  */
-  YYSYMBOL_varorchunk = 146,               /* varorchunk  */
-  YYSYMBOL_varorthe = 147,                 /* varorthe  */
-  YYSYMBOL_chunk = 148,                    /* chunk  */
-  YYSYMBOL_chunktype = 149,                /* chunktype  */
-  YYSYMBOL_object = 150,                   /* object  */
-  YYSYMBOL_refargs = 151,                  /* refargs  */
-  YYSYMBOL_the = 152,                      /* the  */
-  YYSYMBOL_theobj = 153,                   /* theobj  */
-  YYSYMBOL_menu = 154,                     /* menu  */
-  YYSYMBOL_thedatetime = 155,              /* thedatetime  */
-  YYSYMBOL_thenumberof = 156,              /* thenumberof  */
-  YYSYMBOL_inof = 157,                     /* inof  */
-  YYSYMBOL_writablethe = 158,              /* writablethe  */
-  YYSYMBOL_writabletheobj = 159,           /* writabletheobj  */
-  YYSYMBOL_list = 160,                     /* list  */
-  YYSYMBOL_proplist = 161,                 /* proplist  */
-  YYSYMBOL_proppair = 162,                 /* proppair  */
-  YYSYMBOL_unarymath = 163,                /* unarymath  */
-  YYSYMBOL_simpleexpr = 164,               /* simpleexpr  */
-  YYSYMBOL_expr = 165,                     /* expr  */
-  YYSYMBOL_expr_nounarymath = 166,         /* expr_nounarymath  */
-  YYSYMBOL_expr_noeq = 167,                /* expr_noeq  */
-  YYSYMBOL_sprite = 168,                   /* sprite  */
-  YYSYMBOL_exprlist = 169,                 /* exprlist  */
-  YYSYMBOL_nonemptyexprlist = 170          /* nonemptyexprlist  */
+  YYSYMBOL_tMEMBER = 14,                   /* tMEMBER  */
+  YYSYMBOL_tCASTLIB = 15,                  /* tCASTLIB  */
+  YYSYMBOL_tDELETE = 16,                   /* tDELETE  */
+  YYSYMBOL_tDOWN = 17,                     /* tDOWN  */
+  YYSYMBOL_tELSE = 18,                     /* tELSE  */
+  YYSYMBOL_tEXIT = 19,                     /* tEXIT  */
+  YYSYMBOL_tFRAME = 20,                    /* tFRAME  */
+  YYSYMBOL_tGLOBAL = 21,                   /* tGLOBAL  */
+  YYSYMBOL_tGO = 22,                       /* tGO  */
+  YYSYMBOL_tHILITE = 23,                   /* tHILITE  */
+  YYSYMBOL_tIF = 24,                       /* tIF  */
+  YYSYMBOL_tIN = 25,                       /* tIN  */
+  YYSYMBOL_tINTO = 26,                     /* tINTO  */
+  YYSYMBOL_tMACRO = 27,                    /* tMACRO  */
+  YYSYMBOL_tRETURN = 28,                   /* tRETURN  */
+  YYSYMBOL_tMOVIE = 29,                    /* tMOVIE  */
+  YYSYMBOL_tNEXT = 30,                     /* tNEXT  */
+  YYSYMBOL_tOF = 31,                       /* tOF  */
+  YYSYMBOL_tPREVIOUS = 32,                 /* tPREVIOUS  */
+  YYSYMBOL_tPUT = 33,                      /* tPUT  */
+  YYSYMBOL_tREPEAT = 34,                   /* tREPEAT  */
+  YYSYMBOL_tSET = 35,                      /* tSET  */
+  YYSYMBOL_tTHEN = 36,                     /* tTHEN  */
+  YYSYMBOL_tTO = 37,                       /* tTO  */
+  YYSYMBOL_tWHEN = 38,                     /* tWHEN  */
+  YYSYMBOL_tWITH = 39,                     /* tWITH  */
+  YYSYMBOL_tWHILE = 40,                    /* tWHILE  */
+  YYSYMBOL_tFACTORY = 41,                  /* tFACTORY  */
+  YYSYMBOL_tOPEN = 42,                     /* tOPEN  */
+  YYSYMBOL_tPLAY = 43,                     /* tPLAY  */
+  YYSYMBOL_tINSTANCE = 44,                 /* tINSTANCE  */
+  YYSYMBOL_tGE = 45,                       /* tGE  */
+  YYSYMBOL_tLE = 46,                       /* tLE  */
+  YYSYMBOL_tEQ = 47,                       /* tEQ  */
+  YYSYMBOL_tNEQ = 48,                      /* tNEQ  */
+  YYSYMBOL_tAND = 49,                      /* tAND  */
+  YYSYMBOL_tOR = 50,                       /* tOR  */
+  YYSYMBOL_tNOT = 51,                      /* tNOT  */
+  YYSYMBOL_tMOD = 52,                      /* tMOD  */
+  YYSYMBOL_tAFTER = 53,                    /* tAFTER  */
+  YYSYMBOL_tBEFORE = 54,                   /* tBEFORE  */
+  YYSYMBOL_tCONCAT = 55,                   /* tCONCAT  */
+  YYSYMBOL_tCONTAINS = 56,                 /* tCONTAINS  */
+  YYSYMBOL_tSTARTS = 57,                   /* tSTARTS  */
+  YYSYMBOL_tCHAR = 58,                     /* tCHAR  */
+  YYSYMBOL_tCHARS = 59,                    /* tCHARS  */
+  YYSYMBOL_tITEM = 60,                     /* tITEM  */
+  YYSYMBOL_tITEMS = 61,                    /* tITEMS  */
+  YYSYMBOL_tLINE = 62,                     /* tLINE  */
+  YYSYMBOL_tLINES = 63,                    /* tLINES  */
+  YYSYMBOL_tWORD = 64,                     /* tWORD  */
+  YYSYMBOL_tWORDS = 65,                    /* tWORDS  */
+  YYSYMBOL_tABBREVIATED = 66,              /* tABBREVIATED  */
+  YYSYMBOL_tABBREV = 67,                   /* tABBREV  */
+  YYSYMBOL_tABBR = 68,                     /* tABBR  */
+  YYSYMBOL_tLONG = 69,                     /* tLONG  */
+  YYSYMBOL_tSHORT = 70,                    /* tSHORT  */
+  YYSYMBOL_tDATE = 71,                     /* tDATE  */
+  YYSYMBOL_tLAST = 72,                     /* tLAST  */
+  YYSYMBOL_tMENU = 73,                     /* tMENU  */
+  YYSYMBOL_tMENUS = 74,                    /* tMENUS  */
+  YYSYMBOL_tMENUITEM = 75,                 /* tMENUITEM  */
+  YYSYMBOL_tMENUITEMS = 76,                /* tMENUITEMS  */
+  YYSYMBOL_tNUMBER = 77,                   /* tNUMBER  */
+  YYSYMBOL_tTHE = 78,                      /* tTHE  */
+  YYSYMBOL_tTIME = 79,                     /* tTIME  */
+  YYSYMBOL_tXTRAS = 80,                    /* tXTRAS  */
+  YYSYMBOL_tCASTLIBS = 81,                 /* tCASTLIBS  */
+  YYSYMBOL_tSOUND = 82,                    /* tSOUND  */
+  YYSYMBOL_tSPRITE = 83,                   /* tSPRITE  */
+  YYSYMBOL_tINTERSECTS = 84,               /* tINTERSECTS  */
+  YYSYMBOL_tWITHIN = 85,                   /* tWITHIN  */
+  YYSYMBOL_tTELL = 86,                     /* tTELL  */
+  YYSYMBOL_tPROPERTY = 87,                 /* tPROPERTY  */
+  YYSYMBOL_tON = 88,                       /* tON  */
+  YYSYMBOL_tMETHOD = 89,                   /* tMETHOD  */
+  YYSYMBOL_tENDIF = 90,                    /* tENDIF  */
+  YYSYMBOL_tENDREPEAT = 91,                /* tENDREPEAT  */
+  YYSYMBOL_tENDTELL = 92,                  /* tENDTELL  */
+  YYSYMBOL_tASSERTERROR = 93,              /* tASSERTERROR  */
+  YYSYMBOL_94_ = 94,                       /* '<'  */
+  YYSYMBOL_95_ = 95,                       /* '>'  */
+  YYSYMBOL_96_ = 96,                       /* '&'  */
+  YYSYMBOL_97_ = 97,                       /* '+'  */
+  YYSYMBOL_98_ = 98,                       /* '-'  */
+  YYSYMBOL_99_ = 99,                       /* '*'  */
+  YYSYMBOL_100_ = 100,                     /* '/'  */
+  YYSYMBOL_101_n_ = 101,                   /* '\n'  */
+  YYSYMBOL_102_ = 102,                     /* ','  */
+  YYSYMBOL_103_ = 103,                     /* '('  */
+  YYSYMBOL_104_ = 104,                     /* ')'  */
+  YYSYMBOL_105_ = 105,                     /* '['  */
+  YYSYMBOL_106_ = 106,                     /* ']'  */
+  YYSYMBOL_107_ = 107,                     /* ':'  */
+  YYSYMBOL_YYACCEPT = 108,                 /* $accept  */
+  YYSYMBOL_script = 109,                   /* script  */
+  YYSYMBOL_scriptpartlist = 110,           /* scriptpartlist  */
+  YYSYMBOL_scriptpart = 111,               /* scriptpart  */
+  YYSYMBOL_macro = 112,                    /* macro  */
+  YYSYMBOL_factory = 113,                  /* factory  */
+  YYSYMBOL_method = 114,                   /* method  */
+  YYSYMBOL_methodlist = 115,               /* methodlist  */
+  YYSYMBOL_nonemptymethodlist = 116,       /* nonemptymethodlist  */
+  YYSYMBOL_methodlistline = 117,           /* methodlistline  */
+  YYSYMBOL_handler = 118,                  /* handler  */
+  YYSYMBOL_endargdef = 119,                /* endargdef  */
+  YYSYMBOL_CMDID = 120,                    /* CMDID  */
+  YYSYMBOL_ID = 121,                       /* ID  */
+  YYSYMBOL_idlist = 122,                   /* idlist  */
+  YYSYMBOL_nonemptyidlist = 123,           /* nonemptyidlist  */
+  YYSYMBOL_stmt = 124,                     /* stmt  */
+  YYSYMBOL_stmt_insideif = 125,            /* stmt_insideif  */
+  YYSYMBOL_stmtoneliner = 126,             /* stmtoneliner  */
+  YYSYMBOL_proc = 127,                     /* proc  */
+  YYSYMBOL_cmdargs = 128,                  /* cmdargs  */
+  YYSYMBOL_trailingcomma = 129,            /* trailingcomma  */
+  YYSYMBOL_frameargs = 130,                /* frameargs  */
+  YYSYMBOL_asgn = 131,                     /* asgn  */
+  YYSYMBOL_to = 132,                       /* to  */
+  YYSYMBOL_definevars = 133,               /* definevars  */
+  YYSYMBOL_ifstmt = 134,                   /* ifstmt  */
+  YYSYMBOL_ifelsestmt = 135,               /* ifelsestmt  */
+  YYSYMBOL_endif = 136,                    /* endif  */
+  YYSYMBOL_loop = 137,                     /* loop  */
+  YYSYMBOL_tell = 138,                     /* tell  */
+  YYSYMBOL_when = 139,                     /* when  */
+  YYSYMBOL_stmtlist = 140,                 /* stmtlist  */
+  YYSYMBOL_nonemptystmtlist = 141,         /* nonemptystmtlist  */
+  YYSYMBOL_stmtlistline = 142,             /* stmtlistline  */
+  YYSYMBOL_stmtlist_insideif = 143,        /* stmtlist_insideif  */
+  YYSYMBOL_nonemptystmtlist_insideif = 144, /* nonemptystmtlist_insideif  */
+  YYSYMBOL_stmtlistline_insideif = 145,    /* stmtlistline_insideif  */
+  YYSYMBOL_simpleexpr_nounarymath = 146,   /* simpleexpr_nounarymath  */
+  YYSYMBOL_var = 147,                      /* var  */
+  YYSYMBOL_varorchunk = 148,               /* varorchunk  */
+  YYSYMBOL_varorthe = 149,                 /* varorthe  */
+  YYSYMBOL_chunk = 150,                    /* chunk  */
+  YYSYMBOL_chunktype = 151,                /* chunktype  */
+  YYSYMBOL_object = 152,                   /* object  */
+  YYSYMBOL_refargs = 153,                  /* refargs  */
+  YYSYMBOL_the = 154,                      /* the  */
+  YYSYMBOL_theobj = 155,                   /* theobj  */
+  YYSYMBOL_menu = 156,                     /* menu  */
+  YYSYMBOL_thedatetime = 157,              /* thedatetime  */
+  YYSYMBOL_thenumberof = 158,              /* thenumberof  */
+  YYSYMBOL_inof = 159,                     /* inof  */
+  YYSYMBOL_writablethe = 160,              /* writablethe  */
+  YYSYMBOL_writabletheobj = 161,           /* writabletheobj  */
+  YYSYMBOL_list = 162,                     /* list  */
+  YYSYMBOL_proplist = 163,                 /* proplist  */
+  YYSYMBOL_proppair = 164,                 /* proppair  */
+  YYSYMBOL_unarymath = 165,                /* unarymath  */
+  YYSYMBOL_simpleexpr = 166,               /* simpleexpr  */
+  YYSYMBOL_expr = 167,                     /* expr  */
+  YYSYMBOL_expr_nounarymath = 168,         /* expr_nounarymath  */
+  YYSYMBOL_expr_noeq = 169,                /* expr_noeq  */
+  YYSYMBOL_sprite = 170,                   /* sprite  */
+  YYSYMBOL_exprlist = 171,                 /* exprlist  */
+  YYSYMBOL_nonemptyexprlist = 172          /* nonemptyexprlist  */
 };
 typedef enum yysymbol_kind_t yysymbol_kind_t;
 
@@ -656,21 +658,21 @@ union yyalloc
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  189
+#define YYFINAL  195
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   4573
+#define YYLAST   4723
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  106
+#define YYNTOKENS  108
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  65
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  333
+#define YYNRULES  337
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  627
+#define YYNSTATES  635
 
 /* YYMAXUTOK -- Last valid token kind.  */
-#define YYMAXUTOK   346
+#define YYMAXUTOK   348
 
 
 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
@@ -685,15 +687,15 @@ union yyalloc
 static const yytype_int8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-      99,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     101,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,    94,     2,
-     101,   102,    97,    95,   100,    96,     2,    98,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,   105,     2,
-      92,     2,    93,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    96,     2,
+     103,   104,    99,    97,   102,    98,     2,   100,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,   107,     2,
+      94,     2,    95,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,   103,     2,   104,     2,     2,     2,     2,     2,     2,
+       2,   105,     2,   106,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -718,7 +720,7 @@ static const yytype_int8 yytranslate[] =
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,    86,    87,    88,    89,    90,    91
+      85,    86,    87,    88,    89,    90,    91,    92,    93
 };
 
 #if YYDEBUG
@@ -732,33 +734,33 @@ static const yytype_int16 yyrline[] =
      320,   321,   322,   323,   324,   325,   326,   327,   328,   329,
      330,   331,   332,   333,   334,   335,   336,   337,   338,   339,
      340,   341,   342,   343,   344,   345,   346,   347,   348,   349,
-     350,   351,   352,   355,   356,   357,   358,   359,   360,   361,
+     350,   351,   352,   353,   354,   357,   358,   359,   360,   361,
      362,   363,   364,   365,   366,   367,   368,   369,   370,   371,
-     372,   373,   374,   377,   378,   379,   382,   386,   396,   397,
-     400,   401,   402,   403,   404,   405,   408,   409,   410,   413,
-     414,   415,   416,   417,   418,   419,   420,   425,   426,   427,
-     428,   429,   430,   431,   432,   435,   438,   443,   447,   453,
-     458,   461,   466,   470,   476,   483,   483,   489,   494,   500,
-     506,   512,   520,   521,   522,   523,   526,   526,   528,   529,
-     530,   533,   537,   541,   547,   551,   555,   559,   566,   568,
-     570,   572,   574,   578,   582,   586,   588,   589,   593,   599,
-     606,   607,   610,   611,   615,   621,   628,   629,   635,   636,
-     637,   638,   639,   640,   641,   642,   648,   653,   654,   655,
-     656,   657,   658,   661,   663,   664,   667,   668,   671,   672,
-     673,   675,   677,   679,   681,   683,   685,   687,   689,   692,
-     693,   694,   695,   698,   699,   702,   707,   710,   715,   721,
-     722,   723,   724,   725,   728,   729,   730,   731,   732,   735,
-     737,   738,   739,   740,   741,   742,   743,   744,   745,   746,
-     750,   751,   752,   753,   754,   755,   756,   757,   760,   760,
-     762,   763,   766,   767,   768,   769,   770,   773,   774,   775,
-     781,   785,   788,   793,   794,   795,   796,   797,   800,   801,
-     804,   805,   809,   810,   811,   812,   813,   814,   815,   816,
+     372,   373,   374,   375,   376,   379,   380,   381,   384,   388,
+     398,   399,   402,   403,   404,   405,   406,   407,   410,   411,
+     412,   415,   416,   417,   418,   419,   420,   421,   422,   427,
+     428,   429,   430,   431,   432,   433,   434,   437,   440,   445,
+     449,   455,   460,   463,   468,   472,   478,   485,   485,   491,
+     496,   502,   508,   514,   522,   523,   524,   525,   528,   528,
+     530,   531,   532,   535,   539,   543,   549,   553,   557,   561,
+     568,   570,   572,   574,   576,   580,   584,   588,   590,   591,
+     595,   601,   608,   609,   612,   613,   617,   623,   630,   631,
+     637,   638,   639,   640,   641,   642,   643,   644,   650,   655,
+     656,   657,   658,   659,   660,   663,   665,   666,   669,   670,
+     673,   674,   675,   676,   677,   679,   681,   683,   685,   687,
+     689,   691,   693,   696,   697,   698,   699,   702,   703,   706,
+     711,   714,   719,   725,   726,   727,   728,   729,   732,   733,
+     734,   735,   736,   739,   741,   742,   743,   744,   745,   746,
+     747,   748,   749,   750,   754,   755,   756,   757,   758,   759,
+     760,   761,   764,   764,   766,   767,   770,   771,   772,   773,
+     774,   777,   778,   779,   785,   789,   792,   797,   798,   799,
+     800,   801,   804,   805,   808,   809,   813,   814,   815,   816,
      817,   818,   819,   820,   821,   822,   823,   824,   825,   826,
-     827,   834,   835,   836,   837,   838,   839,   840,   841,   842,
+     827,   828,   829,   830,   831,   838,   839,   840,   841,   842,
      843,   844,   845,   846,   847,   848,   849,   850,   851,   852,
-     855,   856,   857,   858,   859,   860,   861,   862,   863,   864,
-     865,   866,   867,   868,   869,   870,   871,   872,   875,   876,
-     879,   880,   883,   887
+     853,   854,   855,   856,   859,   860,   861,   862,   863,   864,
+     865,   866,   867,   868,   869,   870,   871,   872,   873,   874,
+     875,   876,   879,   880,   883,   884,   887,   891
 };
 #endif
 
@@ -777,38 +779,39 @@ yysymbol_name (yysymbol_kind_t yysymbol)
   {
   "end of file", "error", "invalid token", "tUNARY", "tINT", "tFLOAT",
   "tVARID", "tSTRING", "tSYMBOL", "tENDCLAUSE", "tCAST", "tFIELD",
-  "tSCRIPT", "tWINDOW", "tDELETE", "tDOWN", "tELSE", "tEXIT", "tFRAME",
-  "tGLOBAL", "tGO", "tHILITE", "tIF", "tIN", "tINTO", "tMACRO", "tRETURN",
-  "tMOVIE", "tNEXT", "tOF", "tPREVIOUS", "tPUT", "tREPEAT", "tSET",
-  "tTHEN", "tTO", "tWHEN", "tWITH", "tWHILE", "tFACTORY", "tOPEN", "tPLAY",
-  "tINSTANCE", "tGE", "tLE", "tEQ", "tNEQ", "tAND", "tOR", "tNOT", "tMOD",
-  "tAFTER", "tBEFORE", "tCONCAT", "tCONTAINS", "tSTARTS", "tCHAR",
-  "tCHARS", "tITEM", "tITEMS", "tLINE", "tLINES", "tWORD", "tWORDS",
-  "tABBREVIATED", "tABBREV", "tABBR", "tLONG", "tSHORT", "tDATE", "tLAST",
-  "tMENU", "tMENUS", "tMENUITEM", "tMENUITEMS", "tNUMBER", "tTHE", "tTIME",
-  "tXTRAS", "tCASTLIBS", "tSOUND", "tSPRITE", "tINTERSECTS", "tWITHIN",
-  "tTELL", "tPROPERTY", "tON", "tMETHOD", "tENDIF", "tENDREPEAT",
-  "tENDTELL", "tASSERTERROR", "'<'", "'>'", "'&'", "'+'", "'-'", "'*'",
-  "'/'", "'\\n'", "','", "'('", "')'", "'['", "']'", "':'", "$accept",
-  "script", "scriptpartlist", "scriptpart", "macro", "factory", "method",
-  "methodlist", "nonemptymethodlist", "methodlistline", "handler",
-  "endargdef", "CMDID", "ID", "idlist", "nonemptyidlist", "stmt",
-  "stmt_insideif", "stmtoneliner", "proc", "cmdargs", "trailingcomma",
-  "frameargs", "asgn", "to", "definevars", "ifstmt", "ifelsestmt", "endif",
-  "loop", "tell", "when", "stmtlist", "nonemptystmtlist", "stmtlistline",
-  "stmtlist_insideif", "nonemptystmtlist_insideif",
-  "stmtlistline_insideif", "simpleexpr_nounarymath", "var", "varorchunk",
-  "varorthe", "chunk", "chunktype", "object", "refargs", "the", "theobj",
-  "menu", "thedatetime", "thenumberof", "inof", "writablethe",
-  "writabletheobj", "list", "proplist", "proppair", "unarymath",
-  "simpleexpr", "expr", "expr_nounarymath", "expr_noeq", "sprite",
-  "exprlist", "nonemptyexprlist", YY_NULLPTR
+  "tSCRIPT", "tWINDOW", "tMEMBER", "tCASTLIB", "tDELETE", "tDOWN", "tELSE",
+  "tEXIT", "tFRAME", "tGLOBAL", "tGO", "tHILITE", "tIF", "tIN", "tINTO",
+  "tMACRO", "tRETURN", "tMOVIE", "tNEXT", "tOF", "tPREVIOUS", "tPUT",
+  "tREPEAT", "tSET", "tTHEN", "tTO", "tWHEN", "tWITH", "tWHILE",
+  "tFACTORY", "tOPEN", "tPLAY", "tINSTANCE", "tGE", "tLE", "tEQ", "tNEQ",
+  "tAND", "tOR", "tNOT", "tMOD", "tAFTER", "tBEFORE", "tCONCAT",
+  "tCONTAINS", "tSTARTS", "tCHAR", "tCHARS", "tITEM", "tITEMS", "tLINE",
+  "tLINES", "tWORD", "tWORDS", "tABBREVIATED", "tABBREV", "tABBR", "tLONG",
+  "tSHORT", "tDATE", "tLAST", "tMENU", "tMENUS", "tMENUITEM", "tMENUITEMS",
+  "tNUMBER", "tTHE", "tTIME", "tXTRAS", "tCASTLIBS", "tSOUND", "tSPRITE",
+  "tINTERSECTS", "tWITHIN", "tTELL", "tPROPERTY", "tON", "tMETHOD",
+  "tENDIF", "tENDREPEAT", "tENDTELL", "tASSERTERROR", "'<'", "'>'", "'&'",
+  "'+'", "'-'", "'*'", "'/'", "'\\n'", "','", "'('", "')'", "'['", "']'",
+  "':'", "$accept", "script", "scriptpartlist", "scriptpart", "macro",
+  "factory", "method", "methodlist", "nonemptymethodlist",
+  "methodlistline", "handler", "endargdef", "CMDID", "ID", "idlist",
+  "nonemptyidlist", "stmt", "stmt_insideif", "stmtoneliner", "proc",
+  "cmdargs", "trailingcomma", "frameargs", "asgn", "to", "definevars",
+  "ifstmt", "ifelsestmt", "endif", "loop", "tell", "when", "stmtlist",
+  "nonemptystmtlist", "stmtlistline", "stmtlist_insideif",
+  "nonemptystmtlist_insideif", "stmtlistline_insideif",
+  "simpleexpr_nounarymath", "var", "varorchunk", "varorthe", "chunk",
+  "chunktype", "object", "refargs", "the", "theobj", "menu", "thedatetime",
+  "thenumberof", "inof", "writablethe", "writabletheobj", "list",
+  "proplist", "proppair", "unarymath", "simpleexpr", "expr",
+  "expr_nounarymath", "expr_noeq", "sprite", "exprlist",
+  "nonemptyexprlist", YY_NULLPTR
   };
   return yy_sname[yysymbol];
 }
 #endif
 
-#define YYPACT_NINF (-541)
+#define YYPACT_NINF (-534)
 
 #define yypact_value_is_default(Yyn) \
   ((Yyn) == YYPACT_NINF)
@@ -822,69 +825,70 @@ yysymbol_name (yysymbol_kind_t yysymbol)
    STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-    2886,  -541,  3392,  -541,  -541,  -541,  -541,    38,  -541,   -10,
-    -541,  3392,  1990,    38,  2090,  -541,  -541,  3392,  1390,  -541,
-      -5,  -541,  -541,  2190,    53,  3475,  -541,   -54,  -541,  -541,
-    3392,  2190,  1990,  3392,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  2090,  3392,  3392,   -49,  3723,  -541,    73,  2886,  -541,
-    -541,  -541,  -541,  2190,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,    52,
-    -541,  -541,  2290,  2290,  2090,  2090,  2090,  2090,     6,    16,
-      68,  -541,  -541,    84,    26,  -541,  -541,  -541,  -541,  2290,
-    2290,  2290,  2290,  2090,  2090,  2390,  2090,  2090,  2090,  2090,
-    3558,  2090,  2390,  2390,  1490,   688,   -14,    88,    91,  -541,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,   790,
-    -541,    95,  2090,  3996,  3392,  -541,  4196,    97,    99,   890,
-    3392,  2090,  3392,  -541,  -541,    -2,  -541,  -541,   108,   113,
-     990,   114,   118,   119,   591,   121,  3392,  -541,  -541,  -541,
-    -541,   125,  1090,  -541,  3392,  1590,  -541,  -541,  -541,  3772,
-    3794,  3828,  3850,   139,  -541,  -541,  -541,  3392,  -541,  -541,
-    1190,  4393,  -541,   -13,    -3,    36,    60,    65,   139,    64,
-      70,  4380,  -541,  -541,  -541,  2790,  4018,    -8,    45,    56,
-      59,    39,   -42,    66,  -541,  4393,   122,    72,  1690,  -541,
-    -541,   200,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,
-    2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,
-    -541,  -541,  4112,  -541,  -541,  4052,  2969,   129,  -541,  -541,
-    -541,  3641,  3641,  3641,    12,  4209,   201,  -541,  -541,  2090,
-      -7,  -541,  2090,  -541,  -541,  -541,  3723,  3052,  -541,   130,
-    -541,  -541,  -541,  4031,  2390,  2090,  2390,  2090,  2390,  2090,
-    2390,  2090,  -541,  -541,  -541,  -541,    23,  -541,   204,  4449,
-    -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,  -541,
-    1290,  2490,  2390,  2390,  4125,  1790,  -541,  2090,  2090,  2090,
-    2090,  -541,  2090,  2590,  -541,  -541,  2090,  -541,  2790,   133,
-    2090,   -12,   -12,   -12,   -12,  4475,  4475,  -541,    22,   -12,
-     -12,   -12,   -12,    22,    57,    57,  -541,  -541,   133,  2090,
-    2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,
-    2090,  2090,  2090,  2090,  2090,  2090,  2090,  -541,  3301,   218,
-    3052,     6,  -541,   136,  -541,   154,   156,  2090,  2090,  3052,
-    2690,  4222,  3392,  3392,  -541,  -541,  -541,    -7,  -541,  4279,
-    -541,  -541,  -541,   166,  3052,  -541,  3052,  1890,  -541,   441,
-    -541,  3884,  -541,  3906,  -541,  3940,  -541,  -541,  2390,  2090,
-      23,    23,    23,    23,  2390,  -541,  2390,    23,  -541,  -541,
-    2390,  2390,  -541,  -541,  -541,  -541,  -541,  -541,  2090,   155,
-    -541,   133,  4393,  4393,  4393,  4393,  4393,  -541,  4393,  4393,
-    4138,  2090,   157,  4393,  -541,   -12,   -12,   -12,   -12,  4475,
-    4475,  -541,    22,   -12,   -12,   -12,   -12,    22,    57,    57,
-    -541,  -541,   133,  -541,  -541,    -9,  3301,  -541,  3135,  -541,
-    -541,  -541,  -541,  4292,   577,   169,  2090,  2090,  2090,  2090,
-    -541,  -541,  -541,    78,  3392,  -541,  -541,   161,  -541,   252,
-    -541,   133,  2390,  2390,  2390,  2390,  -541,  4393,  2390,  2390,
-    2390,  2390,  -541,   233,   192,  -541,  -541,   133,  -541,   162,
-    2090,   163,  -541,  -541,  3218,   176,  -541,  -541,  3301,  -541,
-    3052,   242,  2090,   182,  -541,  4462,  -541,  3962,  4462,  4462,
-    -541,   183,  -541,  3392,   186,  -541,  -541,  -541,  -541,  -541,
-    -541,  -541,  -541,   197,  2390,  -541,   188,  -541,   133,  -541,
-    3301,  -541,  -541,   206,   196,  2090,  4305,  -541,  2090,  2090,
-    2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,  2090,
-    2090,  2090,  2090,  2090,   221,  3052,   103,  -541,  2390,  -541,
-     194,   206,  -541,   199,  4362,  3052,    51,    51,    51,   458,
-     458,  -541,    27,    51,    51,    51,    51,    27,    62,    62,
-    -541,  -541,  2090,  -541,  -541,  -541,  -541,  -541,  -541,  3052,
-     214,  4462,   215,   207,   208,  -541,  -541
+    3033,  -534,  3586,  -534,  -534,  -534,  -534,  -534,  -534,   108,
+    -534,   -23,  -534,  3586,  2119,   108,  2221,  -534,  -534,  3586,
+    1507,  -534,     6,  -534,  -534,  2323,    32,  3671,  -534,   -59,
+    -534,  -534,  3586,  2323,  2119,  3586,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  2221,  3586,  3586,   -56,  3925,  -534,    61,
+    3033,  -534,  -534,  -534,  -534,  2323,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,     9,  -534,  -534,  2425,  2425,  2425,  2425,  2221,  2221,
+    2221,  2221,     7,   -17,     5,  -534,  -534,    24,    47,  -534,
+    -534,  -534,  -534,  2425,  2425,  2425,  2425,  2425,  2425,  2221,
+    2221,  2527,  2221,  2221,  2221,  2221,  3756,  2221,  2527,  2527,
+    1609,   791,   -12,    39,    62,  -534,  -534,  -534,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,   895,  -534,    66,  2221,  4157,
+    3586,  -534,  4357,    73,    79,   997,  3586,  2221,  3586,  -534,
+    -534,    11,  -534,  -534,    80,    81,  1099,    82,    83,    88,
+    4122,    92,  3586,  -534,  -534,  -534,  -534,    97,  1201,  -534,
+    3586,  1711,  -534,  -534,  -534,  -534,  -534,   609,   682,  3974,
+    3996,   132,  -534,  -534,  -534,  3586,  -534,  -534,  1303,  4554,
+    -534,   -20,    38,    45,    56,    72,   132,    65,    71,  4541,
+    -534,  -534,  -534,  2935,  4179,    50,    90,    93,    94,     2,
+     -82,   -46,  -534,  4554,    67,   100,  1813,  -534,  -534,   176,
+    2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,
+    2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  -534,  -534,
+    4273,  -534,  -534,  4213,  3125,   105,  -534,  -534,  -534,  3841,
+    3841,  3841,    29,  4370,   177,  -534,  -534,  2221,     4,  -534,
+    2221,  -534,  -534,  -534,  3925,  3217,  -534,   106,  -534,  -534,
+    -534,  4192,  2527,  2221,  2527,  2221,  2527,  2221,  2527,  2221,
+    -534,  -534,  -534,  -534,    43,  -534,   186,  4610,  -534,  -534,
+    -534,  -534,  -534,  -534,  -534,  -534,  -534,  -534,  1405,  2629,
+    2527,  2527,  4286,  1915,  -534,  2221,  2221,  2221,  2221,  -534,
+    2221,  2731,  -534,  -534,  2221,  -534,  2935,   115,  2221,   -11,
+     -11,   -11,   -11,   363,   363,  -534,     1,   -11,   -11,   -11,
+     -11,     1,   -19,   -19,  -534,  -534,   115,  2221,  2221,  2221,
+    2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,
+    2221,  2221,  2221,  2221,  2221,  -534,  3493,   201,  3217,     7,
+    -534,   125,  -534,   126,   134,  2221,  2221,  3217,  2833,  4383,
+    3586,  3586,  -534,  -534,  -534,     4,  -534,  4440,  -534,  -534,
+    -534,   133,  3217,  -534,  3217,  2017,  -534,  4009,  -534,  4031,
+    -534,  4066,  -534,  4088,  -534,  -534,  2527,  2221,    43,    43,
+      43,    43,  2527,  -534,  2527,    43,  -534,  -534,  2527,  2527,
+    -534,  -534,  -534,  -534,  -534,  -534,  2221,   135,  -534,   115,
+    4554,  4554,  4554,  4554,  4554,  -534,  4554,  4554,  4299,  2221,
+     137,  4554,  -534,   -11,   -11,   -11,   -11,   363,   363,  -534,
+       1,   -11,   -11,   -11,   -11,     1,   -19,   -19,  -534,  -534,
+     115,  -534,  -534,   -13,  3493,  -534,  3309,  -534,  -534,  -534,
+    -534,  4453,   539,   145,  2221,  2221,  2221,  2221,  -534,  -534,
+    -534,    19,  3586,  -534,  -534,   136,  -534,   229,  -534,   115,
+    2527,  2527,  2527,  2527,  -534,  4554,  2527,  2527,  2527,  2527,
+    -534,   211,   170,  -534,  -534,   115,  -534,   160,  2221,   161,
+    -534,  -534,  3401,   165,  -534,  -534,  3493,  -534,  3217,   230,
+    2221,   167,  -534,   525,  -534,  4101,   525,   525,  -534,   169,
+    -534,  3586,   168,  -534,  -534,  -534,  -534,  -534,  -534,  -534,
+    -534,   198,  2527,  -534,   171,  -534,   115,  -534,  3493,  -534,
+    -534,   183,   185,  2221,  4466,  -534,  2221,  2221,  2221,  2221,
+    2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,  2221,
+    2221,  2221,   209,  3217,    51,  -534,  2527,  -534,   179,   183,
+    -534,   191,  4523,  3217,   124,   124,   124,  4623,  4623,  -534,
+      31,   124,   124,   124,   124,    31,    -5,    -5,  -534,  -534,
+    2221,  -534,  -534,  -534,  -534,  -534,  -534,  3217,   195,   525,
+     196,   192,   199,  -534,  -534
 };
 
 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -892,93 +896,94 @@ static const yytype_int16 yypact[] =
    means the default is an error.  */
 static const yytype_int16 yydefact[] =
 {
-       0,    26,    23,    32,    38,    59,    68,    36,    37,     0,
-      39,    93,   125,    40,     0,    41,    43,     0,     0,    53,
-      54,    56,    57,   125,    58,     0,    66,     0,    69,    67,
-       0,   125,   125,    93,    30,    31,    33,    34,    44,    45,
-      47,    48,    71,    72,    27,    28,    29,    49,    61,    35,
-      46,    50,    51,    52,    55,    64,    65,    62,    63,    42,
-      70,     0,    93,     0,     0,    60,     5,     0,     2,     3,
-       6,     7,     8,   125,     9,    98,   100,   106,   107,   108,
-     101,   102,   103,   104,   105,    75,    36,    74,    76,    78,
-      79,    40,    80,    82,    89,    54,    88,    58,    90,    92,
-      77,    85,    86,    81,    91,    87,    84,    83,    60,     0,
-      73,    24,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   119,    96,     0,    94,   178,   179,   181,   180,    32,
-      38,    59,    68,    39,    53,     0,    33,    44,    47,    71,
-      64,    63,     0,     0,     0,   330,   193,     0,     0,   270,
-     188,   189,   190,   191,   222,   223,   192,   271,   272,   135,
-     273,     0,     0,     0,    93,   120,     0,     0,     0,   135,
-       0,     0,    64,   193,   196,     0,   197,   165,     0,     0,
-     135,     0,     0,     0,     0,     0,    93,    99,   124,     1,
-       4,     0,   135,    10,     0,     0,   199,   215,   198,     0,
-       0,     0,     0,     0,   122,   118,   148,    95,   213,   214,
-     137,   138,   182,    27,    28,    29,    49,    61,    46,    55,
-     219,     0,   268,   269,   130,   188,     0,   178,   179,   181,
-     180,     0,   193,     0,   260,   332,     0,   331,     0,   111,
-     112,    56,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   136,
-     126,   291,   135,   292,   123,     0,     0,     0,   121,   117,
-     110,    43,    30,    31,     0,     0,   250,   146,   147,     0,
-      14,   115,    69,   113,   114,   150,     0,   166,   149,     0,
-     109,    25,   216,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   209,   211,   212,   210,     0,    97,    56,   141,
-     230,   231,   232,   233,   234,   235,   236,   237,   238,   239,
-       0,     0,     0,     0,   135,     0,   187,     0,     0,     0,
-       0,   258,     0,     0,   259,   257,     0,   183,   188,   135,
-       0,   283,   284,   281,   282,   285,   286,   278,   288,   289,
-     290,   280,   279,   287,   274,   275,   276,   277,   135,     0,
+       0,    26,    23,    32,    39,    61,    70,    51,    33,    37,
+      38,     0,    40,    95,   127,    41,     0,    42,    44,     0,
+       0,    55,    56,    58,    59,   127,    60,     0,    68,     0,
+      71,    69,     0,   127,   127,    95,    30,    31,    34,    35,
+      45,    46,    48,    49,    73,    74,    27,    28,    29,    50,
+      63,    36,    47,    52,    53,    54,    57,    66,    67,    64,
+      65,    43,    72,     0,    95,     0,     0,    62,     5,     0,
+       2,     3,     6,     7,     8,   127,     9,   100,   102,   108,
+     109,   110,   103,   104,   105,   106,   107,    77,    37,    76,
+      78,    80,    81,    41,    82,    84,    91,    56,    90,    60,
+      92,    94,    79,    87,    88,    83,    93,    89,    86,    85,
+      62,     0,    75,    24,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   121,    98,     0,    96,   180,
+     181,   183,   182,    32,    39,    61,    70,    51,    33,    40,
+      55,     0,    34,    45,    48,    73,    66,    65,     0,     0,
+       0,   334,   195,     0,     0,   274,   190,   191,   192,   193,
+     226,   227,   194,   275,   276,   137,   277,     0,     0,     0,
+      95,   122,     0,     0,     0,   137,     0,     0,    66,   195,
+     198,     0,   199,   167,     0,     0,   137,     0,     0,     0,
+       0,     0,    95,   101,   126,     1,     4,     0,   137,    10,
+       0,     0,   201,   219,   200,   202,   203,     0,     0,     0,
+       0,     0,   124,   120,   150,    97,   217,   218,   139,   140,
+     184,    27,    28,    29,    50,    63,    47,    57,   223,     0,
+     272,   273,   132,   190,     0,   180,   181,   183,   182,     0,
+     195,     0,   264,   336,     0,   335,     0,   113,   114,    58,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,   136,   128,   172,   151,
-     166,    64,   194,     0,   195,     0,     0,     0,     0,   166,
-       0,     0,    23,     0,    18,    19,    12,    15,    16,     0,
-     163,   170,   171,     0,   167,   168,   166,     0,   200,     0,
-     204,     0,   206,     0,   202,     0,   248,   249,     0,     0,
-      34,    45,    48,    72,    50,   245,    51,    52,   246,   247,
-      62,    63,   221,   225,   224,   220,   328,   329,   136,     0,
-     131,   135,   266,   267,   265,   263,   264,   261,   262,   333,
-     135,   136,     0,   140,   127,   302,   303,   300,   301,   304,
-     305,   297,   307,   308,   309,   299,   298,   306,   293,   294,
-     295,   296,   135,   176,   177,   157,   173,   174,     0,    11,
-     142,   143,   144,     0,     0,     0,    50,    51,    62,    63,
-     251,   252,   145,     0,    93,    17,   116,     0,   169,    22,
-     217,   135,     0,     0,     0,     0,   208,   139,     0,     0,
-       0,     0,   229,     0,     0,   227,   228,   135,   133,     0,
-     136,     0,   184,   129,     0,     0,   152,   175,   172,   153,
-     166,     0,     0,     0,   310,   253,   311,     0,   255,   256,
-      20,     0,   164,    23,     0,   201,   205,   207,   203,   240,
-     242,   243,   241,     0,     0,   244,     0,   132,   135,   185,
-     172,   155,   158,   157,     0,     0,     0,   159,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   138,   128,   295,
+     137,   296,   125,     0,     0,     0,   123,   119,   112,    44,
+      30,    31,     0,     0,   254,   148,   149,     0,    14,   117,
+      71,   115,   116,   152,     0,   168,   151,     0,   111,    25,
+     220,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     213,   215,   216,   214,     0,    99,    58,   143,   234,   235,
+     236,   237,   238,   239,   240,   241,   242,   243,     0,     0,
+       0,     0,   137,     0,   189,     0,     0,     0,     0,   262,
+       0,     0,   263,   261,     0,   185,   190,   137,     0,   287,
+     288,   285,   286,   289,   290,   282,   292,   293,   294,   284,
+     283,   291,   278,   279,   280,   281,   137,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   166,     0,   218,     0,   134,
-       0,   157,   154,     0,     0,   166,   320,   321,   319,   322,
-     323,   316,   325,   326,   327,   318,   317,   324,   312,   313,
-     314,   315,     0,    13,    21,   226,   186,   156,   162,   166,
-       0,   254,     0,     0,     0,   160,   161
+       0,     0,     0,     0,   138,   130,   174,   153,   168,    66,
+     196,     0,   197,     0,     0,     0,     0,   168,     0,     0,
+      23,     0,    18,    19,    12,    15,    16,     0,   165,   172,
+     173,     0,   169,   170,   168,     0,   204,     0,   208,     0,
+     210,     0,   206,     0,   252,   253,     0,     0,    35,    46,
+      49,    74,    52,   249,    53,    54,   250,   251,    64,    65,
+     225,   229,   228,   224,   332,   333,   138,     0,   133,   137,
+     270,   271,   269,   267,   268,   265,   266,   337,   137,   138,
+       0,   142,   129,   306,   307,   304,   305,   308,   309,   301,
+     311,   312,   313,   303,   302,   310,   297,   298,   299,   300,
+     137,   178,   179,   159,   175,   176,     0,    11,   144,   145,
+     146,     0,     0,     0,    52,    53,    64,    65,   255,   256,
+     147,     0,    95,    17,   118,     0,   171,    22,   221,   137,
+       0,     0,     0,     0,   212,   141,     0,     0,     0,     0,
+     233,     0,     0,   231,   232,   137,   135,     0,   138,     0,
+     186,   131,     0,     0,   154,   177,   174,   155,   168,     0,
+       0,     0,   314,   257,   315,     0,   259,   260,    20,     0,
+     166,    23,     0,   205,   209,   211,   207,   244,   246,   247,
+     245,     0,     0,   248,     0,   134,   137,   187,   174,   157,
+     160,   159,     0,     0,     0,   161,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   168,     0,   222,     0,   136,     0,   159,
+     156,     0,     0,   168,   324,   325,   323,   326,   327,   320,
+     329,   330,   331,   322,   321,   328,   316,   317,   318,   319,
+       0,    13,    21,   230,   188,   158,   164,   168,     0,   258,
+       0,     0,     0,   162,   163
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -541,  -541,  -541,   237,  -541,  -541,  -541,  -541,  -541,   -88,
-    -541,  -381,     0,    -1,   -28,  -541,     3,  -360,   -61,  -541,
-       8,  -218,   278,  -541,  -541,  -541,  -541,  -541,  -540,  -541,
-    -541,  -541,  -311,  -541,   -93,  -507,  -541,  -164,  -122,    29,
-     -68,  -541,     7,  -541,  -541,    44,  -541,    -4,  -201,  -541,
-    -541,  -241,  -541,  -541,  -541,  -541,   -19,  -541,    79,    -6,
-    -197,    28,  -150,  -541,  -223
+    -534,  -534,  -534,   226,  -534,  -534,  -534,  -534,  -534,  -103,
+    -534,  -396,     0,    -1,   -28,  -534,     3,  -380,   -65,  -534,
+     -10,  -240,   270,  -534,  -534,  -534,  -534,  -534,  -533,  -534,
+    -534,  -534,  -210,  -534,  -107,  -519,  -534,  -178,  -136,   -18,
+    -134,  -534,    37,  -534,  -534,    96,  -534,   -16,  -208,  -534,
+    -534,  -270,  -534,  -534,  -534,  -534,   -22,  -534,   174,    -6,
+    -198,   -69,  -143,  -534,  -230
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-       0,    67,    68,    69,    70,    71,   395,   396,   397,   398,
-      72,   109,   110,   146,   123,   124,   402,    75,    76,    77,
-     147,   260,   148,    78,   279,    79,    80,    81,   526,    82,
-      83,    84,   403,   404,   405,   475,   476,   477,   149,   150,
-     383,   175,   151,   306,   152,   196,   153,   432,   433,   154,
-     155,   418,   176,   490,   156,   233,   234,   157,   158,   235,
-     262,   535,   160,   236,   237
+       0,    69,    70,    71,    72,    73,   403,   404,   405,   406,
+      74,   111,   112,   152,   127,   128,   410,    77,    78,    79,
+     153,   268,   154,    80,   287,    81,    82,    83,   534,    84,
+      85,    86,   411,   412,   413,   483,   484,   485,   155,   156,
+     391,   181,   157,   314,   158,   202,   159,   440,   441,   160,
+     161,   426,   182,   498,   162,   241,   242,   163,   164,   243,
+     270,   543,   166,   244,   245
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -986,1034 +991,1065 @@ static const yytype_int16 yydefgoto[] =
    number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      73,   111,   392,    74,   188,   183,   159,   524,   163,   263,
-     122,   493,   166,   309,   119,   339,   164,   169,   474,   263,
-     161,   563,   120,   592,   173,   180,   159,   167,   324,   178,
-     263,   168,   122,   277,   185,   387,   358,   261,   248,   179,
-     181,   249,   263,   278,   377,   177,   416,   261,   112,   113,
-     187,   617,   417,   591,   174,   184,   310,   388,   261,   238,
-     263,   122,   186,   332,   311,    73,   312,   192,    73,   479,
-     261,    74,   248,   189,   313,   263,   203,   573,   485,   525,
-     393,   191,   254,   255,   256,   257,   258,   238,   261,   121,
-     170,   171,   394,   320,   114,   499,   115,   327,   116,   321,
-     117,   573,   441,   261,   574,   314,   439,   248,   199,   200,
-     201,   202,   573,   315,   118,   204,   474,   255,   256,   257,
-     258,   452,   580,   581,   582,   583,   207,   210,   211,   316,
-     199,   200,   201,   202,   318,   221,   267,   317,   226,   220,
-     454,   450,   319,   331,   232,   579,   580,   581,   582,   583,
-     328,   193,   194,   472,   257,   258,   265,   198,   289,   582,
-     583,   329,   586,   122,   330,   275,   333,   205,   474,   274,
-     334,   276,   336,   225,   198,   208,   209,   540,   194,   508,
-     509,   510,   511,   206,   501,   122,   514,   239,   263,   293,
-     240,   197,   197,   291,   264,   302,   269,   303,   270,   304,
-     474,   305,   614,   194,   385,   386,   307,   280,   197,   197,
-     197,   197,   281,   283,   212,   517,   261,   284,   285,   564,
-     288,   222,   223,   519,   290,   400,   335,   340,   380,   406,
-     390,   419,   521,   451,   478,   480,   341,   342,   343,   344,
-     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
-     355,   356,   357,   481,   523,   482,   497,   518,   533,   522,
-     542,   543,   553,   554,   557,   559,    73,   338,   588,   379,
-     173,   173,   173,   391,   613,   562,   399,   565,   384,   384,
-     384,   567,   585,   544,   620,   593,    73,    73,   587,   409,
-     589,   411,   612,   413,   525,   415,   616,   558,   618,   556,
-     382,   382,   382,   623,   624,   190,   625,   626,   622,   495,
-     182,   498,   527,   555,   447,     0,     0,   435,     0,     0,
-       0,   442,   443,   444,   445,     0,   446,   448,     0,     0,
-     449,     0,   232,     0,   453,     0,   536,   536,   536,   536,
-     590,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   455,   456,   457,   458,   459,   460,   461,
-     462,   463,   464,   465,   466,   467,   468,   469,   470,   471,
-       0,     0,     0,   408,     0,   410,     0,   412,    73,   414,
-      73,   483,   484,     0,     0,     0,     0,     0,     0,    73,
-       0,   111,   494,     0,     0,     0,     0,     0,     0,   434,
-     434,   436,   437,     0,    73,     0,    73,     0,     0,     0,
-       0,     0,     0,   507,     0,     0,     0,     0,   536,   536,
-     536,   536,   536,   536,   536,   536,   536,   536,   536,   536,
-     536,   536,   536,   536,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   449,     0,     0,     0,     0,
+      75,   113,   194,    76,   501,   532,   482,   189,   165,   180,
+     169,   124,   126,   400,   172,   174,   347,   571,   170,   175,
+     317,   246,   271,   185,   187,   340,   179,   186,   165,   269,
+     385,   184,   271,   256,   126,   332,   191,   366,   600,   269,
+     173,   256,   183,   271,   257,   193,   123,   581,   285,   599,
+     269,   318,   167,   256,   395,   271,   341,   190,   286,   319,
+     342,   195,   269,   126,   192,   197,   625,    75,   424,   198,
+      75,   176,   177,    76,   425,   271,   396,   533,   125,   211,
+     265,   266,   269,   581,   212,   262,   263,   264,   265,   266,
+     271,   246,   447,   401,   590,   591,   328,   269,   263,   264,
+     265,   266,   329,   449,   482,   402,   213,   460,   339,   320,
+     199,   200,   207,   208,   209,   210,   322,   321,   114,   115,
+     548,   200,   116,   117,   323,   214,   462,   324,   588,   589,
+     590,   591,   233,   218,   219,   325,   207,   208,   209,   210,
+     247,   229,   275,   326,   234,   228,   393,   394,   458,   215,
+     240,   327,   622,   200,   480,   594,   482,   335,   516,   517,
+     518,   519,   273,   248,   297,   522,   118,   272,   119,   126,
+     120,   283,   121,   343,   277,   282,   581,   284,   487,   582,
+     278,   288,   289,   291,   292,   509,   122,   493,   482,   293,
+     310,   126,   311,   296,   312,   301,   313,   336,   298,   299,
+     337,   338,   344,   271,   507,   348,   388,   414,   398,   527,
+     269,   204,   205,   206,   315,   427,   525,   459,   529,   486,
+     587,   588,   589,   590,   591,   505,   488,   489,   346,   408,
+     204,   216,   217,   205,   206,   490,   541,   550,   551,   526,
+     531,   530,   561,   562,   349,   350,   351,   352,   353,   354,
+     355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
+     365,   390,   390,   390,   565,   567,   570,   573,   575,   552,
+     593,   596,   595,   533,    75,   597,   601,   387,   179,   179,
+     179,   399,   620,   624,   407,   564,   631,   632,   203,   203,
+     203,   203,   626,   633,    75,    75,   196,   417,   566,   419,
+     634,   421,   503,   423,   188,   506,   535,   203,   203,   203,
+     203,   203,   203,   443,   563,   220,   392,   392,   392,   455,
+       0,     0,   230,   231,     0,     0,   598,     0,   572,   450,
+     451,   452,   453,     0,   454,   456,     0,     0,   457,     0,
+     240,     0,   461,     0,     0,     0,     0,     0,     0,     0,
+       0,   544,   544,   544,   544,     0,     0,     0,     0,     0,
+       0,   463,   464,   465,   466,   467,   468,   469,   470,   471,
+     472,   473,   474,   475,   476,   477,   478,   479,     0,     0,
+       0,     0,     0,   621,     0,     0,    75,     0,    75,   491,
+     492,     0,     0,   628,     0,     0,     0,    75,     0,   113,
+     502,     0,     0,     0,     0,     0,     0,     0,   250,   251,
+     252,   253,    75,     0,    75,   256,     0,   630,   257,   258,
+     259,   515,     0,     0,     0,     0,   545,   546,   547,     0,
+       0,     0,     0,   544,   544,   544,   544,   544,   544,   544,
+     544,   544,   544,   544,   544,   544,   544,   544,   544,     0,
+       0,     0,     0,   457,     0,     0,     0,   260,   261,   262,
+     263,   264,   265,   266,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   549,     0,   416,   544,   418,     0,
+     420,     0,   422,     0,    75,     0,    75,     0,     0,   537,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   126,   442,   442,   444,   445,     0,   604,   605,   606,
+     607,   608,   609,   610,   611,   612,   613,   614,   615,   616,
+     617,   618,   619,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    75,     0,   574,   569,    75,     0,    75,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   536,     0,     0,     0,   541,     0,     0,   491,
-     502,     0,     0,     0,     0,     0,    73,     0,    73,     0,
-       0,   529,     0,     0,   242,   243,   244,   245,   246,   247,
-       0,   248,     0,   122,   249,   250,   251,   506,     0,     0,
-       0,   568,   569,   512,   570,   513,     0,     0,   573,   515,
-     516,   574,   575,   576,     0,   537,   538,   539,     0,     0,
-       0,     0,     0,     0,    73,     0,   566,   561,    73,     0,
-      73,     0,     0,   252,   253,   254,   255,   256,   257,   258,
-       0,     0,   111,     0,     0,     0,     0,     0,     0,     0,
-     577,   578,   579,   580,   581,   582,   583,     0,     0,   594,
-      73,     0,     0,     0,     0,   534,   534,   534,   534,     0,
+     113,   629,     0,     0,     0,     0,   539,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   602,    75,     0,
+     576,   577,   499,   578,   579,   580,   540,   581,     0,     0,
+     582,   583,   584,     0,   250,   251,   252,   253,   254,   255,
+       0,   256,     0,    75,   257,   258,   259,     0,     0,     0,
+     514,     0,     0,    75,     0,     0,   520,     0,   521,     0,
+       0,     0,   523,   524,     0,     0,     0,     0,     0,   585,
+     586,   587,   588,   589,   590,   591,     0,    75,     0,     0,
+       0,     0,     0,   260,   261,   262,   263,   264,   265,   266,
+     302,     0,     0,     0,     0,     0,   303,     0,     0,     0,
+       0,     0,     0,     0,   250,   251,   252,   253,   254,   255,
+       0,   256,     0,     0,   257,   258,   259,     0,   542,   542,
+     542,   542,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   553,   554,   555,   556,     0,     0,
+     557,   558,   559,   560,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,   260,   261,   262,   263,   264,   265,   266,
+       0,     0,     0,   304,     0,     0,     0,     0,     0,   305,
+       0,     0,     0,     0,     0,     0,     0,   250,   251,   252,
+     253,   254,   255,     0,   256,     0,   520,   257,   258,   259,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   545,   546,   547,   548,    73,     0,   549,   550,   551,
-     552,     0,   531,     0,     0,    73,   596,   597,   598,   599,
-     600,   601,   602,   603,   604,   605,   606,   607,   608,   609,
-     610,   611,   532,     0,     0,     0,     0,     0,     0,    73,
-     242,   243,   244,   245,   246,   247,   286,   248,     0,     0,
-     249,   250,   251,   512,   242,   243,   244,   245,   246,   247,
-     621,   248,     0,     0,   249,   250,   251,   534,   534,   534,
-     534,   534,   534,   534,   534,   534,   534,   534,   534,   534,
-     534,   534,   534,     0,     0,     0,     0,   615,     0,   252,
-     253,   254,   255,   256,   257,   258,     0,     0,     0,     0,
-       0,     0,     0,   252,   253,   254,   255,   256,   257,   258,
-     287,   534,   227,   228,     1,   229,   230,    85,   129,   130,
-     131,   132,    86,     8,    87,    88,    10,    89,    90,    91,
-      92,    15,    16,    93,    94,    19,    95,    21,    22,    96,
-      97,    98,    99,    26,     0,    28,    29,   100,   101,   102,
-     103,     0,     0,     0,     0,     0,     0,   135,     0,    34,
-      35,     0,     0,     0,   136,    37,   137,    39,   138,    41,
-     139,    43,    44,    45,    46,    47,    48,    49,    50,    51,
-       0,    52,    53,    54,   140,    56,     0,     0,    57,   141,
-      59,    60,   104,   105,   106,   107,     0,     0,     0,   108,
-       0,     0,     0,   142,   143,     0,     0,     0,     0,   162,
-       0,   145,     0,   231,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,   241,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,   242,   243,   244,   245,   246,   247,   135,
-     248,    34,    35,   249,   250,   251,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,   252,   253,   254,   255,   256,   257,   258,     0,
-     259,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,   271,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,   242,   243,   244,   245,   246,   247,   135,
-     248,   272,   273,   249,   250,   251,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,   252,   253,   254,   255,   256,   257,   258,     0,
-     259,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,   282,    29,   100,
-     101,   102,   103,   242,   243,   244,   245,   246,   247,   135,
-     248,    34,    35,   249,   250,   251,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,   252,   253,   254,   255,   256,   257,   258,     0,
-     259,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,   242,   243,   244,   245,   246,   247,   135,
-     248,    34,    35,   249,   250,   251,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,   252,   253,   254,   255,   256,   257,   258,     0,
-     259,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,   308,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,   242,   243,   244,   245,   246,   247,   135,
-     248,    34,    35,   249,   250,   251,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,   252,   253,   254,   255,   256,   257,   258,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,   420,   137,   421,
-     138,   422,   139,   423,    44,    45,    46,    47,    48,    49,
-      50,   424,   425,   426,   427,    54,   140,    56,   428,   429,
-     430,   431,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,   165,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,   224,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,   292,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,   337,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,   440,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,   500,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,   133,    89,
-      90,    91,    92,    15,    16,    93,    94,   134,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   144,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   144,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,    58,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   195,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,    58,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,   424,     0,   426,    53,    54,   140,    56,     0,     0,
-     430,   431,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   227,   228,     1,   229,   230,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,   486,     0,   487,    53,    54,   140,    56,     0,     0,
-     488,   489,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,   142,   143,     0,     0,     0,
-       0,   162,     0,   145,   125,   126,     1,   127,   128,    85,
-     129,   130,   131,   132,    86,     8,    87,    88,    10,    89,
-      90,    91,    92,    15,    16,    93,    94,    19,    95,    21,
-      22,    96,    97,    98,    99,    26,     0,    28,    29,   100,
-     101,   102,   103,     0,     0,     0,     0,     0,     0,   135,
-       0,    34,    35,     0,     0,     0,   136,    37,   137,    39,
-     138,    41,   139,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,     0,    52,    53,    54,   140,    56,     0,     0,
-      57,   141,    59,    60,   104,   105,   106,   107,     0,     0,
-       0,   108,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   162,     1,   145,     0,     2,     3,     4,     5,     6,
-       7,     8,     0,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-       0,    26,    27,    28,    29,    30,    31,    32,    33,     0,
-       0,     0,     0,     0,     0,     0,     0,    34,    35,     0,
-       0,     0,    36,    37,    38,    39,    40,    41,    42,    43,
-      44,    45,    46,    47,    48,    49,    50,    51,     0,    52,
-      53,    54,    55,    56,     0,     0,    57,    58,    59,    60,
-      61,    62,    63,     0,    64,     1,     0,    65,     0,     3,
-       4,     5,     6,     7,     8,    66,     9,    10,    11,    12,
-      13,    14,    15,    16,     0,    18,    19,    20,    21,    22,
-      23,    24,    25,     0,    26,    27,    28,    29,     0,    31,
-      32,    33,     0,     0,     0,     0,     0,     0,     0,     0,
-      34,    35,     0,     0,     0,    36,    37,    38,    39,    40,
+     542,   542,   542,   542,   542,   542,   542,   542,   542,   542,
+     542,   542,   542,   542,   542,   542,     0,     0,     0,     0,
+     623,     0,     0,     0,     0,     0,   260,   261,   262,   263,
+     264,   265,   266,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   542,   235,   236,     1,   237,   238,
+      87,   133,   134,   135,   136,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,   141,     0,    36,    37,     0,     0,     0,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   146,
+      58,     0,     0,    59,   147,    61,    62,   106,   107,   108,
+     109,     0,     0,     0,   110,     0,     0,     0,   148,   149,
+       0,     0,     0,     0,   168,     0,   151,     0,   239,   129,
+     130,     1,   131,   132,    87,   133,   134,   135,   136,   137,
+     138,    88,    10,    89,    90,    12,    91,    92,    93,    94,
+      17,    18,    95,    96,    21,    97,   249,    24,    98,    99,
+     100,   101,    28,     0,    30,    31,   102,   103,   104,   105,
+     250,   251,   252,   253,   254,   255,   141,   256,    36,    37,
+     257,   258,   259,   142,    39,   143,    41,   144,    43,   145,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,   146,    58,     0,     0,    59,   147,    61,
+      62,   106,   107,   108,   109,     0,     0,     0,   110,   260,
+     261,   262,   263,   264,   265,   266,     0,   267,   168,     0,
+     151,   129,   130,     1,   131,   132,    87,   133,   134,   135,
+     136,   137,   138,    88,    10,    89,    90,    12,    91,    92,
+      93,    94,    17,   279,    95,    96,    21,    97,    23,    24,
+      98,    99,   100,   101,    28,     0,    30,    31,   102,   103,
+     104,   105,   250,   251,   252,   253,   254,   255,   141,   256,
+     280,   281,   257,   258,   259,   142,    39,   143,    41,   144,
+      43,   145,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,     0,    54,    55,    56,   146,    58,     0,     0,    59,
+     147,    61,    62,   106,   107,   108,   109,     0,     0,     0,
+     110,   260,   261,   262,   263,   264,   265,   266,     0,   267,
+     168,     0,   151,   129,   130,     1,   131,   132,    87,   133,
+     134,   135,   136,   137,   138,    88,    10,    89,    90,    12,
+      91,    92,    93,    94,    17,    18,    95,    96,    21,    97,
+      23,    24,    98,    99,   100,   101,    28,     0,   290,    31,
+     102,   103,   104,   105,   250,   251,   252,   253,   254,   255,
+     141,   256,    36,    37,   257,   258,   259,   142,    39,   143,
+      41,   144,    43,   145,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,     0,    54,    55,    56,   146,    58,     0,
+       0,    59,   147,    61,    62,   106,   107,   108,   109,     0,
+       0,     0,   110,   260,   261,   262,   263,   264,   265,   266,
+       0,   267,   168,     0,   151,   129,   130,     1,   131,   132,
+      87,   133,   134,   135,   136,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,   250,   251,   252,   253,
+     254,   255,   141,   256,    36,    37,   257,   258,   259,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   146,
+      58,     0,     0,    59,   147,    61,    62,   106,   107,   108,
+     109,     0,     0,     0,   110,   260,   261,   262,   263,   264,
+     265,   266,     0,   267,   168,     0,   151,   129,   130,     1,
+     131,   132,    87,   133,   134,   135,   136,   137,   138,    88,
+      10,    89,    90,    12,    91,    92,    93,    94,    17,    18,
+      95,    96,    21,    97,   316,    24,    98,    99,   100,   101,
+      28,     0,    30,    31,   102,   103,   104,   105,   250,   251,
+     252,   253,   254,   255,   141,   256,    36,    37,   257,   258,
+     259,   142,    39,   143,    41,   144,    43,   145,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,     0,    54,    55,
+      56,   146,    58,     0,     0,    59,   147,    61,    62,   106,
+     107,   108,   109,     0,     0,     0,   110,   260,   261,   262,
+     263,   264,   265,   266,     0,     0,   168,     0,   151,   129,
+     130,     1,   131,   132,    87,   133,   134,   135,   136,   137,
+     138,    88,    10,    89,    90,    12,    91,    92,    93,    94,
+      17,    18,    95,    96,    21,    97,    23,    24,    98,    99,
+     100,   101,    28,     0,    30,    31,   102,   103,   104,   105,
+       0,     0,     0,     0,     0,     0,   141,     0,    36,    37,
+       0,     0,     0,   142,   428,   143,   429,   144,   430,   145,
+     431,    46,    47,    48,    49,    50,    51,    52,   432,   433,
+     434,   435,    56,   146,    58,   436,   437,   438,   439,    61,
+      62,   106,   107,   108,   109,     0,     0,     0,   110,     0,
+       0,     0,   148,   149,     0,     0,     0,     0,   168,     0,
+     151,   129,   130,     1,   131,   132,    87,   133,   134,   135,
+     136,   137,   138,    88,    10,    89,    90,    12,    91,    92,
+      93,    94,    17,    18,    95,    96,    21,    97,    23,    24,
+      98,    99,   100,   101,    28,     0,    30,    31,   102,   103,
+     104,   105,     0,     0,     0,     0,     0,     0,   141,     0,
+      36,    37,     0,     0,     0,   142,    39,   143,    41,   144,
+      43,   145,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,     0,    54,    55,    56,   146,    58,     0,     0,    59,
+     147,    61,    62,   106,   107,   108,   109,     0,     0,     0,
+     110,     0,     0,     0,   148,   149,     0,     0,   171,     0,
+     168,     0,   151,   129,   130,     1,   131,   132,    87,   133,
+     134,   135,   136,   137,   138,    88,    10,    89,    90,    12,
+      91,    92,    93,    94,    17,    18,    95,    96,    21,    97,
+      23,    24,    98,    99,   100,   101,    28,     0,    30,    31,
+     102,   103,   104,   105,     0,     0,     0,     0,     0,     0,
+     141,     0,    36,    37,     0,     0,     0,   142,    39,   143,
+      41,   144,    43,   145,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,     0,    54,    55,    56,   146,    58,     0,
+       0,    59,   147,    61,    62,   106,   107,   108,   109,     0,
+       0,     0,   110,     0,     0,     0,   148,   149,     0,     0,
+       0,     0,   168,   232,   151,   129,   130,     1,   131,   132,
+      87,   133,   134,   135,   136,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,   141,     0,    36,    37,     0,     0,     0,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   146,
+      58,     0,     0,    59,   147,    61,    62,   106,   107,   108,
+     109,     0,     0,     0,   110,     0,     0,     0,   148,   149,
+       0,     0,     0,     0,   168,   300,   151,   129,   130,     1,
+     131,   132,    87,   133,   134,   135,   136,   137,   138,    88,
+      10,    89,    90,    12,    91,    92,    93,    94,    17,    18,
+      95,    96,    21,    97,    23,    24,    98,    99,   100,   101,
+      28,     0,    30,    31,   102,   103,   104,   105,     0,     0,
+       0,     0,     0,     0,   141,     0,    36,    37,     0,     0,
+       0,   142,    39,   143,    41,   144,    43,   145,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,     0,    54,    55,
+      56,   146,    58,     0,     0,    59,   147,    61,    62,   106,
+     107,   108,   109,     0,     0,     0,   110,     0,     0,     0,
+     148,   149,     0,     0,     0,     0,   168,   345,   151,   129,
+     130,     1,   131,   132,    87,   133,   134,   135,   136,   137,
+     138,    88,    10,    89,    90,    12,    91,    92,    93,    94,
+      17,    18,    95,    96,    21,    97,    23,    24,    98,    99,
+     100,   101,    28,     0,    30,    31,   102,   103,   104,   105,
+       0,     0,     0,     0,     0,     0,   141,     0,    36,    37,
+       0,     0,     0,   142,    39,   143,    41,   144,    43,   145,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,   146,    58,     0,     0,    59,   147,    61,
+      62,   106,   107,   108,   109,     0,     0,     0,   110,     0,
+       0,     0,   148,   149,     0,     0,     0,     0,   168,   448,
+     151,   129,   130,     1,   131,   132,    87,   133,   134,   135,
+     136,   137,   138,    88,    10,    89,    90,    12,    91,    92,
+      93,    94,    17,    18,    95,    96,    21,    97,    23,    24,
+      98,    99,   100,   101,    28,     0,    30,    31,   102,   103,
+     104,   105,     0,     0,     0,     0,     0,     0,   141,     0,
+      36,    37,     0,     0,     0,   142,    39,   143,    41,   144,
+      43,   145,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,     0,    54,    55,    56,   146,    58,     0,     0,    59,
+     147,    61,    62,   106,   107,   108,   109,     0,     0,     0,
+     110,     0,     0,     0,   148,   149,     0,     0,     0,     0,
+     168,   508,   151,   129,   130,     1,   131,   132,    87,   133,
+     134,   135,   136,   137,   138,    88,    10,    89,    90,   139,
+      91,    92,    93,    94,    17,    18,    95,    96,   140,    97,
+      23,    24,    98,    99,   100,   101,    28,     0,    30,    31,
+     102,   103,   104,   105,     0,     0,     0,     0,     0,     0,
+     141,     0,    36,    37,     0,     0,     0,   142,    39,   143,
+      41,   144,    43,   145,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,     0,    54,    55,    56,   146,    58,     0,
+       0,    59,   147,    61,    62,   106,   107,   108,   109,     0,
+       0,     0,   110,     0,     0,     0,   148,   149,     0,     0,
+       0,     0,   150,     0,   151,   129,   130,     1,   131,   132,
+      87,   133,   134,   135,   136,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,   141,     0,    36,    37,     0,     0,     0,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   146,
+      58,     0,     0,    59,   147,    61,    62,   106,   107,   108,
+     109,     0,     0,     0,   110,     0,     0,     0,   148,   149,
+       0,     0,     0,     0,   168,     0,   151,   129,   130,     1,
+     131,   132,    87,   133,   134,   135,   136,   137,   138,    88,
+      10,    89,    90,    12,    91,    92,    93,    94,    17,    18,
+      95,    96,    21,    97,    23,    24,    98,    99,   100,   101,
+      28,     0,    30,    31,   102,   103,   104,   105,     0,     0,
+       0,     0,     0,     0,   141,     0,    36,    37,     0,     0,
+       0,   142,    39,   143,    41,   144,    43,   145,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,     0,    54,    55,
+      56,   146,    58,     0,     0,    59,   147,    61,    62,   106,
+     107,   108,   109,     0,     0,     0,   110,     0,     0,     0,
+     148,   149,     0,     0,     0,     0,   150,     0,   151,   129,
+     130,     1,   131,   132,    87,   133,   134,   135,   136,   137,
+     138,    88,    10,    89,    90,    12,    91,    92,    93,    94,
+      17,    18,    95,    96,    21,    97,    23,    24,    98,    99,
+     100,   101,    28,     0,    30,    31,   102,   103,   104,   105,
+       0,     0,     0,     0,     0,     0,   141,     0,    36,    37,
+       0,     0,     0,   142,    39,   143,    41,   144,    43,   145,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,   146,    58,     0,     0,    59,    60,    61,
+      62,   106,   107,   108,   109,     0,     0,     0,   110,     0,
+       0,     0,   148,   149,     0,     0,     0,     0,   201,     0,
+     151,   129,   130,     1,   131,   132,    87,   133,   134,   135,
+     136,   137,   138,    88,    10,    89,    90,    12,    91,    92,
+      93,    94,    17,    18,    95,    96,    21,    97,    23,    24,
+      98,    99,   100,   101,    28,     0,    30,    31,   102,   103,
+     104,   105,     0,     0,     0,     0,     0,     0,   141,     0,
+      36,    37,     0,     0,     0,   142,    39,   143,    41,   144,
+      43,   145,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,     0,    54,    55,    56,   146,    58,     0,     0,    59,
+      60,    61,    62,   106,   107,   108,   109,     0,     0,     0,
+     110,     0,     0,     0,   148,   149,     0,     0,     0,     0,
+     168,     0,   151,   129,   130,     1,   131,   132,    87,   133,
+     134,   135,   136,   137,   138,    88,    10,    89,    90,    12,
+      91,    92,    93,    94,    17,    18,    95,    96,    21,    97,
+      23,    24,    98,    99,   100,   101,    28,     0,    30,    31,
+     102,   103,   104,   105,     0,     0,     0,     0,     0,     0,
+     141,     0,    36,    37,     0,     0,     0,   142,    39,   143,
+      41,   144,    43,   145,    45,    46,    47,    48,    49,    50,
+      51,    52,   432,     0,   434,    55,    56,   146,    58,     0,
+       0,   438,   439,    61,    62,   106,   107,   108,   109,     0,
+       0,     0,   110,     0,     0,     0,   148,   149,     0,     0,
+       0,     0,   168,     0,   151,   235,   236,     1,   237,   238,
+      87,   133,   134,   135,   136,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,   141,     0,    36,    37,     0,     0,     0,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   146,
+      58,     0,     0,    59,   147,    61,    62,   106,   107,   108,
+     109,     0,     0,     0,   110,     0,     0,     0,   148,   149,
+       0,     0,     0,     0,   168,     0,   151,   129,   130,     1,
+     131,   132,    87,   133,   134,   135,   136,   137,   138,    88,
+      10,    89,    90,    12,    91,    92,    93,    94,    17,    18,
+      95,    96,    21,    97,    23,    24,    98,    99,   100,   101,
+      28,     0,    30,    31,   102,   103,   104,   105,     0,     0,
+       0,     0,     0,     0,   141,     0,    36,    37,     0,     0,
+       0,   142,    39,   143,    41,   144,    43,   145,    45,    46,
+      47,    48,    49,    50,    51,    52,   494,     0,   495,    55,
+      56,   146,    58,     0,     0,   496,   497,    61,    62,   106,
+     107,   108,   109,     0,     0,     0,   110,     0,     0,     0,
+     148,   149,     0,     0,     0,     0,   168,     0,   151,   129,
+     130,     1,   131,   132,    87,   133,   134,   135,   136,   137,
+     138,    88,    10,    89,    90,    12,    91,    92,    93,    94,
+      17,    18,    95,    96,    21,    97,    23,    24,    98,    99,
+     100,   101,    28,     0,    30,    31,   102,   103,   104,   105,
+       0,     0,     0,     0,     0,     0,   141,     0,    36,    37,
+       0,     0,     0,   142,    39,   143,    41,   144,    43,   145,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,   146,    58,     0,     0,    59,   147,    61,
+      62,   106,   107,   108,   109,     0,     0,     0,   110,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   168,     1,
+     151,     0,     2,     3,     4,     5,     6,     7,     8,     9,
+      10,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,     0,
+      28,    29,    30,    31,    32,    33,    34,    35,     0,     0,
+       0,     0,     0,     0,     0,     0,    36,    37,     0,     0,
+       0,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,     0,    54,    55,
+      56,    57,    58,     0,     0,    59,    60,    61,    62,    63,
+      64,    65,     0,    66,     0,     0,    67,     0,     0,     0,
+       0,     1,     0,     0,    68,     3,     4,     5,     6,     7,
+       8,     9,    10,     0,    11,    12,    13,    14,    15,    16,
+      17,    18,     0,    20,    21,    22,    23,    24,    25,    26,
+      27,     0,    28,    29,    30,    31,     0,    33,    34,    35,
+       0,     0,     0,     0,     0,     0,     0,     0,    36,    37,
+       0,     0,     0,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,    57,    58,     0,     0,    59,    60,    61,
+      62,    63,    64,     0,     0,    66,     0,     0,    67,     0,
+       0,     0,     0,     1,     0,     0,   386,     3,     4,     5,
+       6,     7,     8,     9,    10,     0,    11,    12,    13,    14,
+      15,    16,    17,    18,     0,    20,    21,    22,    23,    24,
+      25,    26,    27,     0,    28,    29,    30,    31,     0,    33,
+      34,    35,     0,     0,     0,     0,     0,     0,     0,     0,
+      36,    37,     0,     0,     0,    38,    39,    40,    41,    42,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,     0,    54,    55,    56,    57,    58,     0,     0,    59,
+      60,    61,    62,    63,    64,     0,     0,    66,     0,     0,
+      67,     0,     0,     0,     0,     1,     0,     0,   409,     3,
+       4,     5,     6,     7,     8,     9,    10,     0,    11,    12,
+      13,    14,    15,    16,    17,    18,     0,    20,    21,    22,
+      23,    24,    25,    26,    27,     0,    28,    29,    30,    31,
+       0,    33,    34,    35,     0,     0,     0,     0,     0,     0,
+       0,     0,    36,    37,     0,     0,     0,    38,    39,    40,
       41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
-      51,     0,    52,    53,    54,    55,    56,     0,     0,    57,
-      58,    59,    60,    61,    62,     0,     0,    64,     1,     0,
-      65,     0,     3,     4,     5,     6,     7,     8,   378,     9,
-      10,    11,    12,    13,    14,    15,    16,     0,    18,    19,
-      20,    21,    22,    23,    24,    25,     0,    26,    27,    28,
-      29,     0,    31,    32,    33,     0,     0,     0,     0,     0,
-       0,     0,     0,    34,    35,     0,     0,     0,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,    50,    51,     0,    52,    53,    54,    55,    56,
-       0,     0,    57,    58,    59,    60,    61,    62,     0,     0,
-      64,     1,     0,    65,     0,     3,     4,     5,     6,     7,
-       8,   401,     9,    10,    11,    12,    13,    14,    15,    16,
-       0,    18,    19,    20,    21,    22,    23,    24,    25,     0,
-      26,    27,    28,    29,     0,    31,    32,    33,     0,     0,
-       0,     0,     0,     0,     0,     0,    34,    35,     0,     0,
-       0,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-      45,    46,    47,    48,    49,    50,    51,     0,    52,    53,
-      54,    55,    56,     0,     0,    57,    58,    59,    60,    61,
-      62,     0,     0,    64,     1,     0,    65,     0,     3,     4,
-       5,     6,     7,     8,   528,     9,    10,    11,    12,    13,
-      14,    15,    16,     0,    18,    19,    20,    21,    22,    23,
-      24,    25,     0,    26,    27,    28,    29,     0,    31,    32,
-      33,     0,     0,     0,     0,     0,     0,     0,     0,    34,
-      35,     0,     0,     0,    36,    37,    38,    39,    40,    41,
-      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
-       0,    52,    53,    54,    55,    56,     0,     0,    57,    58,
-      59,    60,    61,    62,     0,     0,    64,     1,     0,    65,
-       0,     3,     4,     5,     6,     7,     8,   560,     9,    10,
-      11,    12,    13,    14,    15,    16,     0,    18,    19,    20,
-      21,    22,    23,    24,    25,     0,    26,    27,    28,    29,
-       0,    31,    32,    33,     0,     0,     0,     0,     0,     0,
-       0,     0,    34,    35,     0,     0,     0,    36,    37,    38,
+      51,    52,    53,     0,    54,    55,    56,    57,    58,     0,
+       0,    59,    60,    61,    62,    63,    64,     0,     0,    66,
+       0,     0,    67,     0,     0,     0,     0,     1,     0,     0,
+     536,     3,     4,     5,     6,     7,     8,     9,    10,     0,
+      11,    12,    13,    14,    15,    16,    17,    18,     0,    20,
+      21,    22,    23,    24,    25,    26,    27,     0,    28,    29,
+      30,    31,     0,    33,    34,    35,     0,     0,     0,     0,
+       0,     0,     0,     0,    36,    37,     0,     0,     0,    38,
       39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
-      49,    50,    51,     0,    52,    53,    54,    55,    56,     0,
-       0,    57,    58,    59,    60,    61,    62,     0,     0,     0,
-       0,     0,    65,     0,     0,     0,     0,     0,     1,     0,
-     473,    85,     3,     4,     5,     6,    86,     8,    87,    88,
-      10,    89,    90,    91,    92,    15,    16,    93,    94,    19,
-      95,    21,    22,    96,    97,    98,    99,    26,     0,    28,
-      29,   100,   101,   102,   103,     0,     0,     0,     0,     0,
-       0,     0,     0,    34,    35,     0,     0,     0,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,
-      48,    49,    50,    51,     0,    52,    53,    54,    55,    56,
-       0,     0,    57,    58,    59,    60,   104,   105,   106,   107,
-       0,     1,     0,   108,    85,     3,     4,     5,     6,    86,
-       8,    87,    88,    10,    89,    90,    91,    92,    15,    16,
-      93,    94,    19,    95,    21,    22,    96,    97,    98,    99,
-      26,     0,    28,    29,   100,   101,   102,   103,     0,     0,
-       0,     0,     0,     0,     0,     0,    34,    35,     0,     0,
-       0,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-      45,    46,    47,    48,    49,    50,    51,     0,    52,    53,
-      54,   172,    56,     0,     0,    57,    58,    59,    60,   104,
-     105,   106,   107,     0,     1,     0,   108,    85,     3,     4,
-       5,     6,    86,     8,    87,    88,    10,    89,    90,    91,
-      92,    15,    16,    93,    94,    19,    95,    21,    22,    96,
-      97,    98,    99,    26,     0,    28,    29,   100,   101,   102,
-     103,     0,     0,     0,     0,     0,     0,     0,     0,    34,
-      35,     0,     0,     0,    36,    37,    38,    39,    40,    41,
-      42,    43,   213,   214,   215,   216,   217,    49,   218,    51,
-       0,    52,    53,   219,    55,    56,     0,     0,    57,    58,
-      59,    60,   104,   105,   106,   107,     0,     1,     0,   108,
-      85,   129,   130,     5,     6,    86,     8,    87,    88,    10,
-      89,    90,    91,    92,    15,    16,    93,    94,    19,    95,
-      21,    22,    96,    97,    98,    99,    26,     0,    28,    29,
-     100,   101,   102,   103,     0,     0,     0,     0,     0,     0,
-       0,     0,    34,    35,     0,     0,     0,   136,    37,   137,
-      39,   138,    41,   139,    43,    44,    45,    46,    47,    48,
-      49,    50,    51,     0,    52,    53,    54,   381,    56,     0,
-       0,    57,    58,    59,    60,   104,   105,   106,   107,     1,
-       0,     0,   108,     3,     4,     5,     6,     7,     8,     0,
-       9,    10,    11,    12,    13,     0,    15,    16,     0,    18,
-      19,    20,    21,    22,    23,    97,    25,     0,    26,     0,
-      28,    29,     0,    31,    32,    33,     0,     0,     0,     0,
-       0,     0,     0,     0,    34,    35,     0,     0,     0,    36,
-      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,
-      47,    48,    49,    50,    51,     0,    52,    53,    54,    55,
-      56,   294,     0,    57,    58,    59,    60,   295,    62,     0,
-       0,     0,     0,     0,    65,   242,   243,   244,   245,   246,
-     247,     0,   248,   296,     0,   249,   250,   251,     0,   297,
-       0,     0,     0,     0,     0,     0,     0,   242,   243,   244,
-     245,   246,   247,     0,   248,     0,     0,   249,   250,   251,
-       0,     0,     0,     0,     0,     0,     0,   298,     0,     0,
-       0,     0,     0,   299,   252,   253,   254,   255,   256,   257,
-     258,   242,   243,   244,   245,   246,   247,     0,   248,   300,
-       0,   249,   250,   251,     0,   301,   252,   253,   254,   255,
-     256,   257,   258,   242,   243,   244,   245,   246,   247,     0,
-     248,     0,     0,   249,   250,   251,     0,     0,     0,     0,
-       0,     0,     0,   503,     0,     0,     0,     0,     0,     0,
-     252,   253,   254,   255,   256,   257,   258,   242,   243,   244,
-     245,   246,   247,     0,   248,   504,     0,   249,   250,   251,
-       0,     0,   252,   253,   254,   255,   256,   257,   258,   242,
-     243,   244,   245,   246,   247,     0,   248,     0,     0,   249,
-     250,   251,     0,     0,     0,     0,     0,     0,     0,   505,
-       0,     0,     0,     0,     0,     0,   252,   253,   254,   255,
-     256,   257,   258,   242,   243,   244,   245,   246,   247,     0,
-     248,   584,     0,   249,   250,   251,     0,     0,   252,   253,
-     254,   255,   256,   257,   258,   568,   569,     0,   570,   571,
-     572,     0,   573,     0,     0,   574,   575,   576,     0,     0,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,    57,
+      58,     0,     0,    59,    60,    61,    62,    63,    64,     0,
+       0,    66,     0,     0,    67,     0,     0,     0,     0,     1,
+       0,     0,   568,     3,     4,     5,     6,     7,     8,     9,
+      10,     0,    11,    12,    13,    14,    15,    16,    17,    18,
+       0,    20,    21,    22,    23,    24,    25,    26,    27,     0,
+      28,    29,    30,    31,     0,    33,    34,    35,     0,     0,
+       0,     0,     0,     0,     0,     0,    36,    37,     0,     0,
+       0,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,     0,    54,    55,
+      56,    57,    58,     0,     0,    59,    60,    61,    62,    63,
+      64,     0,     0,     0,     0,     0,    67,     0,     0,     0,
+       0,     0,     1,     0,   481,    87,     3,     4,     5,     6,
+       7,     8,    88,    10,    89,    90,    12,    91,    92,    93,
+      94,    17,    18,    95,    96,    21,    97,    23,    24,    98,
+      99,   100,   101,    28,     0,    30,    31,   102,   103,   104,
+     105,     0,     0,     0,     0,     0,     0,     0,     0,    36,
+      37,     0,     0,     0,    38,    39,    40,    41,    42,    43,
+      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
+       0,    54,    55,    56,    57,    58,     0,     0,    59,    60,
+      61,    62,   106,   107,   108,   109,     0,     1,     0,   110,
+      87,     3,     4,     5,     6,     7,     8,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,     0,     0,    36,    37,     0,     0,     0,    38,
+      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   178,
+      58,     0,     0,    59,    60,    61,    62,   106,   107,   108,
+     109,     0,     1,     0,   110,    87,     3,     4,     5,     6,
+       7,     8,    88,    10,    89,    90,    12,    91,    92,    93,
+      94,    17,    18,    95,    96,    21,    97,    23,    24,    98,
+      99,   100,   101,    28,     0,    30,    31,   102,   103,   104,
+     105,     0,     0,     0,     0,     0,     0,     0,     0,    36,
+      37,     0,     0,     0,    38,    39,    40,    41,    42,    43,
+      44,    45,   221,   222,   223,   224,   225,    51,   226,    53,
+       0,    54,    55,   227,    57,    58,     0,     0,    59,    60,
+      61,    62,   106,   107,   108,   109,     0,     1,     0,   110,
+      87,   133,   134,     5,     6,   137,   138,    88,    10,    89,
+      90,    12,    91,    92,    93,    94,    17,    18,    95,    96,
+      21,    97,    23,    24,    98,    99,   100,   101,    28,     0,
+      30,    31,   102,   103,   104,   105,     0,     0,     0,     0,
+       0,     0,     0,     0,    36,    37,     0,     0,     0,   142,
+      39,   143,    41,   144,    43,   145,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,     0,    54,    55,    56,   389,
+      58,     0,     0,    59,    60,    61,    62,   106,   107,   108,
+     109,     1,     0,     0,   110,     3,     4,     5,     6,     7,
+       8,     9,    10,     0,    11,    12,    13,    14,    15,     0,
+      17,    18,     0,    20,    21,    22,    23,    24,    25,    99,
+      27,     0,    28,     0,    30,    31,     0,    33,    34,    35,
+       0,     0,     0,     0,     0,     0,     0,     0,    36,    37,
+       0,     0,     0,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,     0,
+      54,    55,    56,    57,    58,   306,     0,    59,    60,    61,
+      62,   307,    64,     0,     0,     0,     0,     0,    67,   250,
+     251,   252,   253,   254,   255,     0,   256,   308,     0,   257,
+     258,   259,     0,   309,     0,     0,     0,     0,     0,     0,
+     510,   250,   251,   252,   253,   254,   255,     0,   256,     0,
+       0,   257,   258,   259,   250,   251,   252,   253,   254,   255,
+       0,   256,   511,     0,   257,   258,   259,     0,   260,   261,
+     262,   263,   264,   265,   266,     0,   250,   251,   252,   253,
+     254,   255,     0,   256,     0,     0,   257,   258,   259,     0,
+     260,   261,   262,   263,   264,   265,   266,   512,     0,     0,
+       0,     0,     0,   260,   261,   262,   263,   264,   265,   266,
+       0,   250,   251,   252,   253,   254,   255,     0,   256,   513,
+       0,   257,   258,   259,     0,   260,   261,   262,   263,   264,
+     265,   266,   592,   250,   251,   252,   253,   254,   255,     0,
+     256,     0,     0,   257,   258,   259,   576,   577,     0,   578,
+     579,   580,     0,   581,     0,     0,   582,   583,   584,   294,
+     260,   261,   262,   263,   264,   265,   266,   250,   251,   252,
+     253,   254,   255,     0,   256,     0,     0,   257,   258,   259,
+       0,     0,   260,   261,   262,   263,   264,   265,   266,     0,
+       0,     0,     0,   274,     0,   585,   586,   587,   588,   589,
+     590,   591,   250,   251,   252,   253,   254,   255,     0,   256,
+       0,     0,   257,   258,   259,     0,   260,   261,   262,   263,
+     264,   265,   266,   295,   250,   251,   252,   253,   254,   255,
+       0,   256,     0,     0,   257,   258,   259,   250,   251,   252,
+     253,   254,   255,     0,   256,     0,     0,   257,   258,   259,
+       0,   260,   261,   262,   263,   264,   265,   266,   250,   251,
+     252,   253,   254,   255,     0,   256,     0,     0,   257,   258,
+     259,     0,     0,   260,   261,   262,   263,   264,   265,   266,
+       0,   333,     0,   334,     0,     0,   260,   261,   262,   263,
+     264,   265,   266,     0,   415,     0,   334,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   260,   261,   262,
+     263,   264,   265,   266,     0,     0,     0,   334,   367,   368,
+     369,   370,   371,   372,     0,   373,     0,     0,   374,   375,
+     376,   367,   368,   369,   370,   371,   372,     0,   373,     0,
+       0,   374,   375,   376,   367,   368,   369,   370,   371,   372,
+       0,   373,     0,     0,   374,   375,   376,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   377,   378,   379,
+     380,   381,   382,   383,     0,   384,     0,     0,     0,     0,
+     377,   378,   379,   380,   381,   382,   383,     0,   446,     0,
+       0,     0,     0,   377,   378,   379,   380,   381,   382,   383,
+       0,   528,   250,   251,   252,   253,   254,   255,     0,   256,
+       0,     0,   257,   258,   259,   250,   251,   252,   253,   254,
+     255,     0,   256,     0,     0,   257,   258,   259,   250,   251,
+     252,   253,   254,   255,     0,   256,     0,     0,   257,   258,
+     259,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   260,   261,   262,   263,   264,   265,   266,   276,     0,
+       0,     0,     0,     0,   260,   261,   262,   263,   264,   265,
+     266,   397,     0,     0,     0,     0,     0,   260,   261,   262,
+     263,   264,   265,   266,   500,   250,   251,   252,   253,   254,
+     255,     0,   256,     0,     0,   257,   258,   259,   250,   251,
+     252,   253,   254,   255,     0,   256,     0,     0,   257,   258,
+     259,   250,   251,   252,   253,   254,   255,     0,   256,     0,
+       0,   257,   258,   259,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   260,   261,   262,   263,   264,   265,
+     266,   504,     0,     0,     0,     0,     0,   260,   261,   262,
+     263,   264,   265,   266,   538,     0,     0,     0,     0,     0,
+     260,   261,   262,   263,   264,   265,   266,   603,   250,   251,
+     252,   253,   254,   255,     0,   256,     0,     0,   257,   258,
+     259,     0,     0,     0,     0,     0,   250,   251,   252,   253,
+     254,   255,     0,   256,     0,     0,   257,   258,   259,   250,
+     251,   252,   253,   254,   255,     0,   256,     0,     0,   257,
+     258,   259,     0,     0,     0,     0,     0,   260,   261,   262,
+     263,   264,   265,   266,   627,   330,   331,     0,     0,     0,
+       0,     0,     0,     0,     0,   260,   261,   262,   263,   264,
+     265,   266,     0,     0,     0,     0,     0,     0,   260,   261,
+     262,   263,   264,   265,   266,   367,   368,   369,   370,   371,
+     372,     0,   373,     0,     0,   374,   375,   376,   576,   577,
+       0,   578,     0,     0,     0,   581,     0,     0,   582,   583,
+     584,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     266,     0,   252,   253,   254,   255,   256,   257,   258,   242,
-     243,   244,   245,   246,   247,     0,   248,     0,     0,   249,
-     250,   251,     0,     0,   577,   578,   579,   580,   581,   582,
-     583,   242,   243,   244,   245,   246,   247,     0,   248,     0,
-       0,   249,   250,   251,   242,   243,   244,   245,   246,   247,
-       0,   248,     0,     0,   249,   250,   251,     0,   252,   253,
-     254,   255,   256,   257,   258,   242,   243,   244,   245,   246,
-     247,     0,   248,     0,     0,   249,   250,   251,     0,     0,
-     252,   253,   254,   255,   256,   257,   258,     0,   325,     0,
-     326,     0,     0,   252,   253,   254,   255,   256,   257,   258,
-       0,   407,     0,   326,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   252,   253,   254,   255,   256,   257,
-     258,     0,     0,     0,   326,   359,   360,   361,   362,   363,
-     364,     0,   365,     0,     0,   366,   367,   368,   359,   360,
-     361,   362,   363,   364,     0,   365,     0,     0,   366,   367,
-     368,   359,   360,   361,   362,   363,   364,     0,   365,     0,
-       0,   366,   367,   368,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   369,   370,   371,   372,   373,   374,
-     375,     0,   376,     0,     0,     0,     0,   369,   370,   371,
-     372,   373,   374,   375,     0,   438,     0,     0,     0,     0,
-     369,   370,   371,   372,   373,   374,   375,     0,   520,   242,
-     243,   244,   245,   246,   247,     0,   248,     0,     0,   249,
-     250,   251,   242,   243,   244,   245,   246,   247,     0,   248,
-       0,     0,   249,   250,   251,   242,   243,   244,   245,   246,
-     247,     0,   248,     0,     0,   249,   250,   251,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,   252,   253,
-     254,   255,   256,   257,   258,   268,     0,     0,     0,     0,
-       0,   252,   253,   254,   255,   256,   257,   258,   389,     0,
-       0,     0,     0,     0,   252,   253,   254,   255,   256,   257,
-     258,   492,   242,   243,   244,   245,   246,   247,     0,   248,
-       0,     0,   249,   250,   251,   242,   243,   244,   245,   246,
-     247,     0,   248,     0,     0,   249,   250,   251,   242,   243,
-     244,   245,   246,   247,     0,   248,     0,     0,   249,   250,
-     251,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   252,   253,   254,   255,   256,   257,   258,   496,     0,
-       0,     0,     0,     0,   252,   253,   254,   255,   256,   257,
-     258,   530,     0,     0,     0,     0,     0,   252,   253,   254,
-     255,   256,   257,   258,   595,   242,   243,   244,   245,   246,
-     247,     0,   248,     0,     0,   249,   250,   251,     0,     0,
-       0,     0,     0,   242,   243,   244,   245,   246,   247,     0,
-     248,     0,     0,   249,   250,   251,   242,   243,   244,   245,
-     246,   247,     0,   248,     0,     0,   249,   250,   251,     0,
-       0,     0,     0,     0,   252,   253,   254,   255,   256,   257,
-     258,   619,   322,   323,     0,     0,     0,     0,     0,     0,
-       0,     0,   252,   253,   254,   255,   256,   257,   258,     0,
-       0,     0,     0,     0,     0,   252,   253,   254,   255,   256,
-     257,   258,   359,   360,   361,   362,   363,   364,     0,   365,
-       0,     0,   366,   367,   368,   568,   569,     0,   570,   571,
-     572,     0,   573,     0,     0,   574,   575,   576,   242,   243,
-     244,   245,     0,     0,     0,   248,     0,     0,   249,   250,
-     251,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,   369,   370,   371,   372,   373,   374,   375,     0,     0,
-       0,     0,     0,     0,   577,   578,   579,   580,   581,   582,
-     583,     0,     0,     0,     0,     0,     0,   252,   253,   254,
-     255,   256,   257,   258
+       0,     0,     0,     0,   377,   378,   379,   380,   381,   382,
+     383,     0,     0,     0,     0,     0,     0,   585,   586,   587,
+     588,   589,   590,   591
 };
 
 static const yytype_int16 yycheck[] =
 {
-       0,     2,     9,     0,    65,    33,    12,    16,    14,   159,
-      11,   392,    18,   210,     7,   238,    17,    23,   378,   169,
-      13,   528,    32,   563,    25,    31,    32,    32,   225,    30,
-     180,    23,    33,    35,    62,    23,   259,   159,    50,    31,
-      32,    53,   192,    45,   262,    99,    23,   169,    10,    11,
-      99,   591,    29,   560,    25,    61,    69,    45,   180,   101,
-     210,    62,    63,   105,    77,    65,    69,    73,    68,   380,
-     192,    68,    50,     0,    77,   225,    70,    50,   389,    88,
-      87,    73,    94,    95,    96,    97,    98,   101,   210,    99,
-      37,    38,    99,    29,    56,   406,    58,   105,    60,    29,
-      62,    50,   325,   225,    53,    69,   324,    50,   114,   115,
-     116,   117,    50,    77,    76,    99,   476,    95,    96,    97,
-      98,   339,    95,    96,    97,    98,   100,   133,   134,    69,
-     136,   137,   138,   139,    69,   141,   164,    77,   144,   140,
-     358,   338,    77,   104,   145,    94,    95,    96,    97,    98,
-     105,    99,   100,   376,    97,    98,   162,   113,   186,    97,
-      98,   105,   543,   164,   105,   171,   100,    99,   528,   170,
-     104,   172,   100,   144,   130,   131,   132,    99,   100,   420,
-     421,   422,   423,    99,   407,   186,   427,    99,   338,   195,
-      99,   112,   113,   194,    99,    56,    99,    58,    99,    60,
-     560,    62,    99,   100,   272,   273,   207,    99,   129,   130,
-     131,   132,    99,    99,   135,   438,   338,    99,    99,   530,
-      99,   142,   143,   441,    99,   286,   104,    27,    99,    99,
-      29,    27,   450,   100,    16,    99,   242,   243,   244,   245,
-     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,
-     256,   257,   258,    99,   472,    99,    90,   102,    89,   102,
-      99,     9,    29,    71,   102,   102,   266,   238,    71,   266,
-     271,   272,   273,   279,   585,    99,   282,    35,   271,   272,
-     273,    99,    99,   501,   595,    89,   286,   287,   102,   295,
-     102,   297,    71,   299,    88,   301,   102,   520,    99,   517,
-     271,   272,   273,    89,    89,    68,    99,    99,   619,   397,
-      32,   404,   476,   514,   333,    -1,    -1,   321,    -1,    -1,
-      -1,   327,   328,   329,   330,    -1,   332,   333,    -1,    -1,
-     336,    -1,   333,    -1,   340,    -1,   486,   487,   488,   489,
-     558,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   359,   360,   361,   362,   363,   364,   365,
-     366,   367,   368,   369,   370,   371,   372,   373,   374,   375,
-      -1,    -1,    -1,   294,    -1,   296,    -1,   298,   378,   300,
-     380,   387,   388,    -1,    -1,    -1,    -1,    -1,    -1,   389,
-      -1,   392,   393,    -1,    -1,    -1,    -1,    -1,    -1,   320,
-     321,   322,   323,    -1,   404,    -1,   406,    -1,    -1,    -1,
-      -1,    -1,    -1,   419,    -1,    -1,    -1,    -1,   568,   569,
-     570,   571,   572,   573,   574,   575,   576,   577,   578,   579,
-     580,   581,   582,   583,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,   451,    -1,    -1,    -1,    -1,
+       0,     2,    67,     0,   400,    18,   386,    35,    14,    27,
+      16,    34,    13,     9,    20,    25,   246,   536,    19,    25,
+     218,   103,   165,    33,    34,   107,    27,    33,    34,   165,
+     270,    32,   175,    52,    35,   233,    64,   267,   571,   175,
+      34,    52,   101,   186,    55,   101,     9,    52,    37,   568,
+     186,    71,    15,    52,    25,   198,   102,    63,    47,    79,
+     106,     0,   198,    64,    65,    75,   599,    67,    25,    75,
+      70,    39,    40,    70,    31,   218,    47,    90,   101,    72,
+      99,   100,   218,    52,   101,    96,    97,    98,    99,   100,
+     233,   103,   332,    89,    99,   100,    31,   233,    97,    98,
+      99,   100,    31,   333,   484,   101,   101,   347,   106,    71,
+     101,   102,   118,   119,   120,   121,    71,    79,    10,    11,
+     101,   102,    14,    15,    79,   101,   366,    71,    97,    98,
+      99,   100,   150,   139,   140,    79,   142,   143,   144,   145,
+     101,   147,   170,    71,   150,   146,   280,   281,   346,   102,
+     151,    79,   101,   102,   384,   551,   536,   107,   428,   429,
+     430,   431,   168,   101,   192,   435,    58,   101,    60,   170,
+      62,   177,    64,   106,   101,   176,    52,   178,   388,    55,
+     101,   101,   101,   101,   101,   415,    78,   397,   568,   101,
+      58,   192,    60,   101,    62,   201,    64,   107,   101,   200,
+     107,   107,   102,   346,   414,    29,   101,   101,    31,   449,
+     346,   115,   116,   117,   215,    29,   446,   102,   458,    18,
+      96,    97,    98,    99,   100,    92,   101,   101,   246,   294,
+     134,   135,   136,   137,   138,   101,    91,   101,     9,   104,
+     480,   104,    31,    73,   250,   251,   252,   253,   254,   255,
+     256,   257,   258,   259,   260,   261,   262,   263,   264,   265,
+     266,   279,   280,   281,   104,   104,   101,    37,   101,   509,
+     101,    73,   104,    90,   274,   104,    91,   274,   279,   280,
+     281,   287,    73,   104,   290,   525,    91,    91,   114,   115,
+     116,   117,   101,   101,   294,   295,    70,   303,   528,   305,
+     101,   307,   405,   309,    34,   412,   484,   133,   134,   135,
+     136,   137,   138,   329,   522,   141,   279,   280,   281,   341,
+      -1,    -1,   148,   149,    -1,    -1,   566,    -1,   538,   335,
+     336,   337,   338,    -1,   340,   341,    -1,    -1,   344,    -1,
+     341,    -1,   348,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   494,   495,   496,   497,    -1,    -1,    -1,    -1,    -1,
+      -1,   367,   368,   369,   370,   371,   372,   373,   374,   375,
+     376,   377,   378,   379,   380,   381,   382,   383,    -1,    -1,
+      -1,    -1,    -1,   593,    -1,    -1,   386,    -1,   388,   395,
+     396,    -1,    -1,   603,    -1,    -1,    -1,   397,    -1,   400,
+     401,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    45,    46,
+      47,    48,   412,    -1,   414,    52,    -1,   627,    55,    56,
+      57,   427,    -1,    -1,    -1,    -1,   495,   496,   497,    -1,
+      -1,    -1,    -1,   576,   577,   578,   579,   580,   581,   582,
+     583,   584,   585,   586,   587,   588,   589,   590,   591,    -1,
+      -1,    -1,    -1,   459,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   502,    -1,   302,   620,   304,    -1,
+     306,    -1,   308,    -1,   484,    -1,   486,    -1,    -1,   486,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   612,    -1,    -1,    -1,   494,    -1,    -1,   390,
-      29,    -1,    -1,    -1,    -1,    -1,   476,    -1,   478,    -1,
-      -1,   478,    -1,    -1,    43,    44,    45,    46,    47,    48,
-      -1,    50,    -1,   494,    53,    54,    55,   418,    -1,    -1,
-      -1,    43,    44,   424,    46,   426,    -1,    -1,    50,   430,
-     431,    53,    54,    55,    -1,   487,   488,   489,    -1,    -1,
-      -1,    -1,    -1,    -1,   524,    -1,   532,   524,   528,    -1,
-     530,    -1,    -1,    92,    93,    94,    95,    96,    97,    98,
-      -1,    -1,   543,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      92,    93,    94,    95,    96,    97,    98,    -1,    -1,   565,
-     560,    -1,    -1,    -1,    -1,   486,   487,   488,   489,    -1,
+      -1,   502,   328,   329,   330,   331,    -1,   576,   577,   578,
+     579,   580,   581,   582,   583,   584,   585,   586,   587,   588,
+     589,   590,   591,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   532,    -1,   540,   532,   536,    -1,   538,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   502,   503,   504,   505,   585,    -1,   508,   509,   510,
-     511,    -1,    15,    -1,    -1,   595,   568,   569,   570,   571,
-     572,   573,   574,   575,   576,   577,   578,   579,   580,   581,
-     582,   583,    35,    -1,    -1,    -1,    -1,    -1,    -1,   619,
-      43,    44,    45,    46,    47,    48,    35,    50,    -1,    -1,
-      53,    54,    55,   554,    43,    44,    45,    46,    47,    48,
-     612,    50,    -1,    -1,    53,    54,    55,   568,   569,   570,
-     571,   572,   573,   574,   575,   576,   577,   578,   579,   580,
-     581,   582,   583,    -1,    -1,    -1,    -1,   588,    -1,    92,
-      93,    94,    95,    96,    97,    98,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    92,    93,    94,    95,    96,    97,    98,
-      99,   612,     4,     5,     6,     7,     8,     9,    10,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    -1,    37,    38,    39,    40,    41,
-      42,    -1,    -1,    -1,    -1,    -1,    -1,    49,    -1,    51,
-      52,    -1,    -1,    -1,    56,    57,    58,    59,    60,    61,
-      62,    63,    64,    65,    66,    67,    68,    69,    70,    71,
-      -1,    73,    74,    75,    76,    77,    -1,    -1,    80,    81,
-      82,    83,    84,    85,    86,    87,    -1,    -1,    -1,    91,
-      -1,    -1,    -1,    95,    96,    -1,    -1,    -1,    -1,   101,
-      -1,   103,    -1,   105,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
-     100,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
-     100,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
-     100,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
-     100,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    92,    93,    94,    95,    96,    97,    98,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    72,    73,    74,    75,    76,    77,    78,    79,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    99,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,   102,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,   102,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,   102,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,   102,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,   102,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    95,    96,    -1,    -1,    -1,
-      -1,   101,    -1,   103,     4,     5,     6,     7,     8,     9,
-      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,
-      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,    31,    32,    33,    34,    35,    -1,    37,    38,    39,
-      40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,    59,
-      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    -1,    73,    74,    75,    76,    77,    -1,    -1,
-      80,    81,    82,    83,    84,    85,    86,    87,    -1,    -1,
-      -1,    91,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   101,     6,   103,    -1,     9,    10,    11,    12,    13,
-      14,    15,    -1,    17,    18,    19,    20,    21,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
-      -1,    35,    36,    37,    38,    39,    40,    41,    42,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    51,    52,    -1,
-      -1,    -1,    56,    57,    58,    59,    60,    61,    62,    63,
-      64,    65,    66,    67,    68,    69,    70,    71,    -1,    73,
-      74,    75,    76,    77,    -1,    -1,    80,    81,    82,    83,
-      84,    85,    86,    -1,    88,     6,    -1,    91,    -1,    10,
-      11,    12,    13,    14,    15,    99,    17,    18,    19,    20,
-      21,    22,    23,    24,    -1,    26,    27,    28,    29,    30,
-      31,    32,    33,    -1,    35,    36,    37,    38,    -1,    40,
-      41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      51,    52,    -1,    -1,    -1,    56,    57,    58,    59,    60,
+     551,   620,    -1,    -1,    -1,    -1,    17,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   573,   568,    -1,
+      45,    46,   398,    48,    49,    50,    37,    52,    -1,    -1,
+      55,    56,    57,    -1,    45,    46,    47,    48,    49,    50,
+      -1,    52,    -1,   593,    55,    56,    57,    -1,    -1,    -1,
+     426,    -1,    -1,   603,    -1,    -1,   432,    -1,   434,    -1,
+      -1,    -1,   438,   439,    -1,    -1,    -1,    -1,    -1,    94,
+      95,    96,    97,    98,    99,   100,    -1,   627,    -1,    -1,
+      -1,    -1,    -1,    94,    95,    96,    97,    98,    99,   100,
+      31,    -1,    -1,    -1,    -1,    -1,    37,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    45,    46,    47,    48,    49,    50,
+      -1,    52,    -1,    -1,    55,    56,    57,    -1,   494,   495,
+     496,   497,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   510,   511,   512,   513,    -1,    -1,
+     516,   517,   518,   519,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    94,    95,    96,    97,    98,    99,   100,
+      -1,    -1,    -1,    31,    -1,    -1,    -1,    -1,    -1,    37,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,
+      48,    49,    50,    -1,    52,    -1,   562,    55,    56,    57,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     576,   577,   578,   579,   580,   581,   582,   583,   584,   585,
+     586,   587,   588,   589,   590,   591,    -1,    -1,    -1,    -1,
+     596,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,    97,
+      98,    99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   620,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    51,    -1,    53,    54,    -1,    -1,    -1,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,    -1,    -1,    93,    -1,    -1,    -1,    97,    98,
+      -1,    -1,    -1,    -1,   103,    -1,   105,    -1,   107,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    -1,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    -1,    -1,    82,    83,    84,
+      85,    86,    87,    88,    89,    -1,    -1,    -1,    93,    94,
+      95,    96,    97,    98,    99,   100,    -1,   102,   103,    -1,
+     105,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    -1,    39,    40,    41,    42,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    -1,    75,    76,    77,    78,    79,    -1,    -1,    82,
+      83,    84,    85,    86,    87,    88,    89,    -1,    -1,    -1,
+      93,    94,    95,    96,    97,    98,    99,   100,    -1,   102,
+     103,    -1,   105,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    -1,    39,    40,
+      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
+      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
+      71,    72,    73,    -1,    75,    76,    77,    78,    79,    -1,
+      -1,    82,    83,    84,    85,    86,    87,    88,    89,    -1,
+      -1,    -1,    93,    94,    95,    96,    97,    98,    99,   100,
+      -1,   102,   103,    -1,   105,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,
+      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,    -1,    -1,    93,    94,    95,    96,    97,    98,
+      99,   100,    -1,   102,   103,    -1,   105,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    -1,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    88,    89,    -1,    -1,    -1,    93,    94,    95,    96,
+      97,    98,    99,   100,    -1,    -1,   103,    -1,   105,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    -1,    39,    40,    41,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89,    -1,    -1,    -1,    93,    -1,
+      -1,    -1,    97,    98,    -1,    -1,    -1,    -1,   103,    -1,
+     105,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    -1,    39,    40,    41,    42,
+      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,
+      53,    54,    -1,    -1,    -1,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    -1,    75,    76,    77,    78,    79,    -1,    -1,    82,
+      83,    84,    85,    86,    87,    88,    89,    -1,    -1,    -1,
+      93,    -1,    -1,    -1,    97,    98,    -1,    -1,   101,    -1,
+     103,    -1,   105,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    -1,    39,    40,
+      41,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,
+      51,    -1,    53,    54,    -1,    -1,    -1,    58,    59,    60,
+      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
+      71,    72,    73,    -1,    75,    76,    77,    78,    79,    -1,
+      -1,    82,    83,    84,    85,    86,    87,    88,    89,    -1,
+      -1,    -1,    93,    -1,    -1,    -1,    97,    98,    -1,    -1,
+      -1,    -1,   103,   104,   105,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    51,    -1,    53,    54,    -1,    -1,    -1,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,    -1,    -1,    93,    -1,    -1,    -1,    97,    98,
+      -1,    -1,    -1,    -1,   103,   104,   105,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    -1,    39,    40,    41,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    51,    -1,    53,    54,    -1,    -1,
+      -1,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    88,    89,    -1,    -1,    -1,    93,    -1,    -1,    -1,
+      97,    98,    -1,    -1,    -1,    -1,   103,   104,   105,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    -1,    39,    40,    41,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    -1,    -1,    82,    83,    84,
+      85,    86,    87,    88,    89,    -1,    -1,    -1,    93,    -1,
+      -1,    -1,    97,    98,    -1,    -1,    -1,    -1,   103,   104,
+     105,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    -1,    39,    40,    41,    42,
+      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,
+      53,    54,    -1,    -1,    -1,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    -1,    75,    76,    77,    78,    79,    -1,    -1,    82,
+      83,    84,    85,    86,    87,    88,    89,    -1,    -1,    -1,
+      93,    -1,    -1,    -1,    97,    98,    -1,    -1,    -1,    -1,
+     103,   104,   105,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    -1,    39,    40,
+      41,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,
+      51,    -1,    53,    54,    -1,    -1,    -1,    58,    59,    60,
       61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
-      71,    -1,    73,    74,    75,    76,    77,    -1,    -1,    80,
-      81,    82,    83,    84,    85,    -1,    -1,    88,     6,    -1,
-      91,    -1,    10,    11,    12,    13,    14,    15,    99,    17,
-      18,    19,    20,    21,    22,    23,    24,    -1,    26,    27,
-      28,    29,    30,    31,    32,    33,    -1,    35,    36,    37,
-      38,    -1,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    51,    52,    -1,    -1,    -1,    56,    57,
-      58,    59,    60,    61,    62,    63,    64,    65,    66,    67,
-      68,    69,    70,    71,    -1,    73,    74,    75,    76,    77,
-      -1,    -1,    80,    81,    82,    83,    84,    85,    -1,    -1,
-      88,     6,    -1,    91,    -1,    10,    11,    12,    13,    14,
-      15,    99,    17,    18,    19,    20,    21,    22,    23,    24,
-      -1,    26,    27,    28,    29,    30,    31,    32,    33,    -1,
-      35,    36,    37,    38,    -1,    40,    41,    42,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    51,    52,    -1,    -1,
-      -1,    56,    57,    58,    59,    60,    61,    62,    63,    64,
-      65,    66,    67,    68,    69,    70,    71,    -1,    73,    74,
-      75,    76,    77,    -1,    -1,    80,    81,    82,    83,    84,
-      85,    -1,    -1,    88,     6,    -1,    91,    -1,    10,    11,
-      12,    13,    14,    15,    99,    17,    18,    19,    20,    21,
-      22,    23,    24,    -1,    26,    27,    28,    29,    30,    31,
-      32,    33,    -1,    35,    36,    37,    38,    -1,    40,    41,
-      42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    51,
-      52,    -1,    -1,    -1,    56,    57,    58,    59,    60,    61,
-      62,    63,    64,    65,    66,    67,    68,    69,    70,    71,
-      -1,    73,    74,    75,    76,    77,    -1,    -1,    80,    81,
-      82,    83,    84,    85,    -1,    -1,    88,     6,    -1,    91,
-      -1,    10,    11,    12,    13,    14,    15,    99,    17,    18,
-      19,    20,    21,    22,    23,    24,    -1,    26,    27,    28,
-      29,    30,    31,    32,    33,    -1,    35,    36,    37,    38,
-      -1,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,
+      71,    72,    73,    -1,    75,    76,    77,    78,    79,    -1,
+      -1,    82,    83,    84,    85,    86,    87,    88,    89,    -1,
+      -1,    -1,    93,    -1,    -1,    -1,    97,    98,    -1,    -1,
+      -1,    -1,   103,    -1,   105,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    51,    -1,    53,    54,    -1,    -1,    -1,    58,
       59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
-      69,    70,    71,    -1,    73,    74,    75,    76,    77,    -1,
-      -1,    80,    81,    82,    83,    84,    85,    -1,    -1,    -1,
-      -1,    -1,    91,    -1,    -1,    -1,    -1,    -1,     6,    -1,
-      99,     9,    10,    11,    12,    13,    14,    15,    16,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    33,    34,    35,    -1,    37,
-      38,    39,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    51,    52,    -1,    -1,    -1,    56,    57,
-      58,    59,    60,    61,    62,    63,    64,    65,    66,    67,
-      68,    69,    70,    71,    -1,    73,    74,    75,    76,    77,
-      -1,    -1,    80,    81,    82,    83,    84,    85,    86,    87,
-      -1,     6,    -1,    91,     9,    10,    11,    12,    13,    14,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,    -1,    -1,    93,    -1,    -1,    -1,    97,    98,
+      -1,    -1,    -1,    -1,   103,    -1,   105,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    -1,    39,    40,    41,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    51,    -1,    53,    54,    -1,    -1,
+      -1,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    88,    89,    -1,    -1,    -1,    93,    -1,    -1,    -1,
+      97,    98,    -1,    -1,    -1,    -1,   103,    -1,   105,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    -1,    37,    38,    39,    40,    41,    42,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    51,    52,    -1,    -1,
-      -1,    56,    57,    58,    59,    60,    61,    62,    63,    64,
-      65,    66,    67,    68,    69,    70,    71,    -1,    73,    74,
-      75,    76,    77,    -1,    -1,    80,    81,    82,    83,    84,
-      85,    86,    87,    -1,     6,    -1,    91,     9,    10,    11,
-      12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
-      22,    23,    24,    25,    26,    27,    28,    29,    30,    31,
-      32,    33,    34,    35,    -1,    37,    38,    39,    40,    41,
-      42,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    51,
-      52,    -1,    -1,    -1,    56,    57,    58,    59,    60,    61,
-      62,    63,    64,    65,    66,    67,    68,    69,    70,    71,
-      -1,    73,    74,    75,    76,    77,    -1,    -1,    80,    81,
-      82,    83,    84,    85,    86,    87,    -1,     6,    -1,    91,
+      35,    36,    37,    -1,    39,    40,    41,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    -1,    -1,    82,    83,    84,
+      85,    86,    87,    88,    89,    -1,    -1,    -1,    93,    -1,
+      -1,    -1,    97,    98,    -1,    -1,    -1,    -1,   103,    -1,
+     105,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,
+      33,    34,    35,    36,    37,    -1,    39,    40,    41,    42,
+      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,
+      53,    54,    -1,    -1,    -1,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    -1,    75,    76,    77,    78,    79,    -1,    -1,    82,
+      83,    84,    85,    86,    87,    88,    89,    -1,    -1,    -1,
+      93,    -1,    -1,    -1,    97,    98,    -1,    -1,    -1,    -1,
+     103,    -1,   105,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    -1,    39,    40,
+      41,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,
+      51,    -1,    53,    54,    -1,    -1,    -1,    58,    59,    60,
+      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
+      71,    72,    73,    -1,    75,    76,    77,    78,    79,    -1,
+      -1,    82,    83,    84,    85,    86,    87,    88,    89,    -1,
+      -1,    -1,    93,    -1,    -1,    -1,    97,    98,    -1,    -1,
+      -1,    -1,   103,    -1,   105,     4,     5,     6,     7,     8,
        9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
       19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    51,    -1,    53,    54,    -1,    -1,    -1,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,    -1,    -1,    93,    -1,    -1,    -1,    97,    98,
+      -1,    -1,    -1,    -1,   103,    -1,   105,     4,     5,     6,
+       7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    -1,    39,    40,    41,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    51,    -1,    53,    54,    -1,    -1,
+      -1,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    88,    89,    -1,    -1,    -1,    93,    -1,    -1,    -1,
+      97,    98,    -1,    -1,    -1,    -1,   103,    -1,   105,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    -1,    39,    40,    41,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    51,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    -1,    -1,    82,    83,    84,
+      85,    86,    87,    88,    89,    -1,    -1,    -1,    93,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   103,     6,
+     105,    -1,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    -1,    19,    20,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    -1,
+      37,    38,    39,    40,    41,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    53,    54,    -1,    -1,
+      -1,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    88,    -1,    90,    -1,    -1,    93,    -1,    -1,    -1,
+      -1,     6,    -1,    -1,   101,    10,    11,    12,    13,    14,
+      15,    16,    17,    -1,    19,    20,    21,    22,    23,    24,
+      25,    26,    -1,    28,    29,    30,    31,    32,    33,    34,
+      35,    -1,    37,    38,    39,    40,    -1,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    -1,    -1,    82,    83,    84,
+      85,    86,    87,    -1,    -1,    90,    -1,    -1,    93,    -1,
+      -1,    -1,    -1,     6,    -1,    -1,   101,    10,    11,    12,
+      13,    14,    15,    16,    17,    -1,    19,    20,    21,    22,
+      23,    24,    25,    26,    -1,    28,    29,    30,    31,    32,
+      33,    34,    35,    -1,    37,    38,    39,    40,    -1,    42,
+      43,    44,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      53,    54,    -1,    -1,    -1,    58,    59,    60,    61,    62,
+      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
+      73,    -1,    75,    76,    77,    78,    79,    -1,    -1,    82,
+      83,    84,    85,    86,    87,    -1,    -1,    90,    -1,    -1,
+      93,    -1,    -1,    -1,    -1,     6,    -1,    -1,   101,    10,
+      11,    12,    13,    14,    15,    16,    17,    -1,    19,    20,
+      21,    22,    23,    24,    25,    26,    -1,    28,    29,    30,
+      31,    32,    33,    34,    35,    -1,    37,    38,    39,    40,
+      -1,    42,    43,    44,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    53,    54,    -1,    -1,    -1,    58,    59,    60,
+      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,
+      71,    72,    73,    -1,    75,    76,    77,    78,    79,    -1,
+      -1,    82,    83,    84,    85,    86,    87,    -1,    -1,    90,
+      -1,    -1,    93,    -1,    -1,    -1,    -1,     6,    -1,    -1,
+     101,    10,    11,    12,    13,    14,    15,    16,    17,    -1,
+      19,    20,    21,    22,    23,    24,    25,    26,    -1,    28,
       29,    30,    31,    32,    33,    34,    35,    -1,    37,    38,
-      39,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    51,    52,    -1,    -1,    -1,    56,    57,    58,
+      39,    40,    -1,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    53,    54,    -1,    -1,    -1,    58,
       59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
-      69,    70,    71,    -1,    73,    74,    75,    76,    77,    -1,
-      -1,    80,    81,    82,    83,    84,    85,    86,    87,     6,
-      -1,    -1,    91,    10,    11,    12,    13,    14,    15,    -1,
-      17,    18,    19,    20,    21,    -1,    23,    24,    -1,    26,
-      27,    28,    29,    30,    31,    32,    33,    -1,    35,    -1,
-      37,    38,    -1,    40,    41,    42,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    51,    52,    -1,    -1,    -1,    56,
-      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,
-      67,    68,    69,    70,    71,    -1,    73,    74,    75,    76,
-      77,    29,    -1,    80,    81,    82,    83,    35,    85,    -1,
-      -1,    -1,    -1,    -1,    91,    43,    44,    45,    46,    47,
-      48,    -1,    50,    29,    -1,    53,    54,    55,    -1,    35,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    43,    44,    45,
-      46,    47,    48,    -1,    50,    -1,    -1,    53,    54,    55,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    29,    -1,    -1,
-      -1,    -1,    -1,    35,    92,    93,    94,    95,    96,    97,
-      98,    43,    44,    45,    46,    47,    48,    -1,    50,    29,
-      -1,    53,    54,    55,    -1,    35,    92,    93,    94,    95,
-      96,    97,    98,    43,    44,    45,    46,    47,    48,    -1,
-      50,    -1,    -1,    53,    54,    55,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,
-      92,    93,    94,    95,    96,    97,    98,    43,    44,    45,
-      46,    47,    48,    -1,    50,    29,    -1,    53,    54,    55,
-      -1,    -1,    92,    93,    94,    95,    96,    97,    98,    43,
-      44,    45,    46,    47,    48,    -1,    50,    -1,    -1,    53,
-      54,    55,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    29,
-      -1,    -1,    -1,    -1,    -1,    -1,    92,    93,    94,    95,
-      96,    97,    98,    43,    44,    45,    46,    47,    48,    -1,
-      50,    29,    -1,    53,    54,    55,    -1,    -1,    92,    93,
-      94,    95,    96,    97,    98,    43,    44,    -1,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    -1,    -1,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    -1,
+      -1,    90,    -1,    -1,    93,    -1,    -1,    -1,    -1,     6,
+      -1,    -1,   101,    10,    11,    12,    13,    14,    15,    16,
+      17,    -1,    19,    20,    21,    22,    23,    24,    25,    26,
+      -1,    28,    29,    30,    31,    32,    33,    34,    35,    -1,
+      37,    38,    39,    40,    -1,    42,    43,    44,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    53,    54,    -1,    -1,
+      -1,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+      67,    68,    69,    70,    71,    72,    73,    -1,    75,    76,
+      77,    78,    79,    -1,    -1,    82,    83,    84,    85,    86,
+      87,    -1,    -1,    -1,    -1,    -1,    93,    -1,    -1,    -1,
+      -1,    -1,     6,    -1,   101,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      34,    35,    36,    37,    -1,    39,    40,    41,    42,    43,
+      44,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,
+      54,    -1,    -1,    -1,    58,    59,    60,    61,    62,    63,
+      64,    65,    66,    67,    68,    69,    70,    71,    72,    73,
+      -1,    75,    76,    77,    78,    79,    -1,    -1,    82,    83,
+      84,    85,    86,    87,    88,    89,    -1,     6,    -1,    93,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    53,    54,    -1,    -1,    -1,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,    -1,     6,    -1,    93,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,
+      34,    35,    36,    37,    -1,    39,    40,    41,    42,    43,
+      44,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,
+      54,    -1,    -1,    -1,    58,    59,    60,    61,    62,    63,
+      64,    65,    66,    67,    68,    69,    70,    71,    72,    73,
+      -1,    75,    76,    77,    78,    79,    -1,    -1,    82,    83,
+      84,    85,    86,    87,    88,    89,    -1,     6,    -1,    93,
+       9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,    32,    33,    34,    35,    36,    37,    -1,
+      39,    40,    41,    42,    43,    44,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    53,    54,    -1,    -1,    -1,    58,
+      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,
+      69,    70,    71,    72,    73,    -1,    75,    76,    77,    78,
+      79,    -1,    -1,    82,    83,    84,    85,    86,    87,    88,
+      89,     6,    -1,    -1,    93,    10,    11,    12,    13,    14,
+      15,    16,    17,    -1,    19,    20,    21,    22,    23,    -1,
+      25,    26,    -1,    28,    29,    30,    31,    32,    33,    34,
+      35,    -1,    37,    -1,    39,    40,    -1,    42,    43,    44,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    54,
+      -1,    -1,    -1,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    -1,
+      75,    76,    77,    78,    79,    31,    -1,    82,    83,    84,
+      85,    37,    87,    -1,    -1,    -1,    -1,    -1,    93,    45,
+      46,    47,    48,    49,    50,    -1,    52,    31,    -1,    55,
+      56,    57,    -1,    37,    -1,    -1,    -1,    -1,    -1,    -1,
+      31,    45,    46,    47,    48,    49,    50,    -1,    52,    -1,
+      -1,    55,    56,    57,    45,    46,    47,    48,    49,    50,
+      -1,    52,    31,    -1,    55,    56,    57,    -1,    94,    95,
+      96,    97,    98,    99,   100,    -1,    45,    46,    47,    48,
+      49,    50,    -1,    52,    -1,    -1,    55,    56,    57,    -1,
+      94,    95,    96,    97,    98,    99,   100,    31,    -1,    -1,
+      -1,    -1,    -1,    94,    95,    96,    97,    98,    99,   100,
+      -1,    45,    46,    47,    48,    49,    50,    -1,    52,    31,
+      -1,    55,    56,    57,    -1,    94,    95,    96,    97,    98,
+      99,   100,    31,    45,    46,    47,    48,    49,    50,    -1,
+      52,    -1,    -1,    55,    56,    57,    45,    46,    -1,    48,
+      49,    50,    -1,    52,    -1,    -1,    55,    56,    57,    37,
+      94,    95,    96,    97,    98,    99,   100,    45,    46,    47,
+      48,    49,    50,    -1,    52,    -1,    -1,    55,    56,    57,
+      -1,    -1,    94,    95,    96,    97,    98,    99,   100,    -1,
+      -1,    -1,    -1,    36,    -1,    94,    95,    96,    97,    98,
+      99,   100,    45,    46,    47,    48,    49,    50,    -1,    52,
+      -1,    -1,    55,    56,    57,    -1,    94,    95,    96,    97,
+      98,    99,   100,   101,    45,    46,    47,    48,    49,    50,
+      -1,    52,    -1,    -1,    55,    56,    57,    45,    46,    47,
+      48,    49,    50,    -1,    52,    -1,    -1,    55,    56,    57,
+      -1,    94,    95,    96,    97,    98,    99,   100,    45,    46,
+      47,    48,    49,    50,    -1,    52,    -1,    -1,    55,    56,
+      57,    -1,    -1,    94,    95,    96,    97,    98,    99,   100,
+      -1,   102,    -1,   104,    -1,    -1,    94,    95,    96,    97,
+      98,    99,   100,    -1,   102,    -1,   104,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,    -1,    -1,    -1,   104,    45,    46,
+      47,    48,    49,    50,    -1,    52,    -1,    -1,    55,    56,
+      57,    45,    46,    47,    48,    49,    50,    -1,    52,    -1,
+      -1,    55,    56,    57,    45,    46,    47,    48,    49,    50,
+      -1,    52,    -1,    -1,    55,    56,    57,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,    -1,   102,    -1,    -1,    -1,    -1,
+      94,    95,    96,    97,    98,    99,   100,    -1,   102,    -1,
+      -1,    -1,    -1,    94,    95,    96,    97,    98,    99,   100,
+      -1,   102,    45,    46,    47,    48,    49,    50,    -1,    52,
+      -1,    -1,    55,    56,    57,    45,    46,    47,    48,    49,
+      50,    -1,    52,    -1,    -1,    55,    56,    57,    45,    46,
+      47,    48,    49,    50,    -1,    52,    -1,    -1,    55,    56,
+      57,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    94,    95,    96,    97,    98,    99,   100,   101,    -1,
+      -1,    -1,    -1,    -1,    94,    95,    96,    97,    98,    99,
+     100,   101,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,   101,    45,    46,    47,    48,    49,
+      50,    -1,    52,    -1,    -1,    55,    56,    57,    45,    46,
+      47,    48,    49,    50,    -1,    52,    -1,    -1,    55,    56,
+      57,    45,    46,    47,    48,    49,    50,    -1,    52,    -1,
+      -1,    55,    56,    57,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    94,    95,    96,    97,    98,    99,
+     100,   101,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,   101,    -1,    -1,    -1,    -1,    -1,
+      94,    95,    96,    97,    98,    99,   100,   101,    45,    46,
+      47,    48,    49,    50,    -1,    52,    -1,    -1,    55,    56,
+      57,    -1,    -1,    -1,    -1,    -1,    45,    46,    47,    48,
+      49,    50,    -1,    52,    -1,    -1,    55,    56,    57,    45,
+      46,    47,    48,    49,    50,    -1,    52,    -1,    -1,    55,
+      56,    57,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100,   101,    84,    85,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    94,    95,    96,    97,    98,
+      99,   100,    -1,    -1,    -1,    -1,    -1,    -1,    94,    95,
+      96,    97,    98,    99,   100,    45,    46,    47,    48,    49,
+      50,    -1,    52,    -1,    -1,    55,    56,    57,    45,    46,
+      -1,    48,    -1,    -1,    -1,    52,    -1,    -1,    55,    56,
+      57,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      34,    -1,    92,    93,    94,    95,    96,    97,    98,    43,
-      44,    45,    46,    47,    48,    -1,    50,    -1,    -1,    53,
-      54,    55,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    43,    44,    45,    46,    47,    48,    -1,    50,    -1,
-      -1,    53,    54,    55,    43,    44,    45,    46,    47,    48,
-      -1,    50,    -1,    -1,    53,    54,    55,    -1,    92,    93,
-      94,    95,    96,    97,    98,    43,    44,    45,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    -1,    -1,
-      92,    93,    94,    95,    96,    97,    98,    -1,   100,    -1,
-     102,    -1,    -1,    92,    93,    94,    95,    96,    97,    98,
-      -1,   100,    -1,   102,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    -1,    -1,    -1,   102,    43,    44,    45,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    43,    44,
-      45,    46,    47,    48,    -1,    50,    -1,    -1,    53,    54,
-      55,    43,    44,    45,    46,    47,    48,    -1,    50,    -1,
-      -1,    53,    54,    55,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    -1,   100,    -1,    -1,    -1,    -1,    92,    93,    94,
-      95,    96,    97,    98,    -1,   100,    -1,    -1,    -1,    -1,
-      92,    93,    94,    95,    96,    97,    98,    -1,   100,    43,
-      44,    45,    46,    47,    48,    -1,    50,    -1,    -1,    53,
-      54,    55,    43,    44,    45,    46,    47,    48,    -1,    50,
-      -1,    -1,    53,    54,    55,    43,    44,    45,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    92,    93,
-      94,    95,    96,    97,    98,    99,    -1,    -1,    -1,    -1,
-      -1,    92,    93,    94,    95,    96,    97,    98,    99,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    99,    43,    44,    45,    46,    47,    48,    -1,    50,
-      -1,    -1,    53,    54,    55,    43,    44,    45,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    43,    44,
-      45,    46,    47,    48,    -1,    50,    -1,    -1,    53,    54,
-      55,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    92,    93,    94,    95,    96,    97,    98,    99,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    99,    -1,    -1,    -1,    -1,    -1,    92,    93,    94,
-      95,    96,    97,    98,    99,    43,    44,    45,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    -1,    -1,
-      -1,    -1,    -1,    43,    44,    45,    46,    47,    48,    -1,
-      50,    -1,    -1,    53,    54,    55,    43,    44,    45,    46,
-      47,    48,    -1,    50,    -1,    -1,    53,    54,    55,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    99,    82,    83,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    92,    93,    94,    95,    96,    97,    98,    -1,
-      -1,    -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,
-      97,    98,    43,    44,    45,    46,    47,    48,    -1,    50,
-      -1,    -1,    53,    54,    55,    43,    44,    -1,    46,    47,
-      48,    -1,    50,    -1,    -1,    53,    54,    55,    43,    44,
-      45,    46,    -1,    -1,    -1,    50,    -1,    -1,    53,    54,
-      55,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    92,    93,    94,    95,    96,    97,    98,    -1,    -1,
-      -1,    -1,    -1,    -1,    92,    93,    94,    95,    96,    97,
-      98,    -1,    -1,    -1,    -1,    -1,    -1,    92,    93,    94,
-      95,    96,    97,    98
+      -1,    -1,    -1,    -1,    94,    95,    96,    97,    98,    99,
+     100,    -1,    -1,    -1,    -1,    -1,    -1,    94,    95,    96,
+      97,    98,    99,   100
 };
 
 /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
    state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     6,     9,    10,    11,    12,    13,    14,    15,    17,
-      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
-      28,    29,    30,    31,    32,    33,    35,    36,    37,    38,
-      39,    40,    41,    42,    51,    52,    56,    57,    58,    59,
+       0,     6,     9,    10,    11,    12,    13,    14,    15,    16,
+      17,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    33,    34,    35,    37,    38,
+      39,    40,    41,    42,    43,    44,    53,    54,    58,    59,
       60,    61,    62,    63,    64,    65,    66,    67,    68,    69,
-      70,    71,    73,    74,    75,    76,    77,    80,    81,    82,
-      83,    84,    85,    86,    88,    91,    99,   107,   108,   109,
-     110,   111,   116,   118,   122,   123,   124,   125,   129,   131,
-     132,   133,   135,   136,   137,     9,    14,    16,    17,    19,
-      20,    21,    22,    25,    26,    28,    31,    32,    33,    34,
-      39,    40,    41,    42,    84,    85,    86,    87,    91,   117,
-     118,   119,    10,    11,    56,    58,    60,    62,    76,   148,
-      32,    99,   119,   120,   121,     4,     5,     7,     8,    10,
-      11,    12,    13,    18,    27,    49,    56,    58,    60,    62,
-      76,    81,    95,    96,   101,   103,   119,   126,   128,   144,
-     145,   148,   150,   152,   155,   156,   160,   163,   164,   165,
-     168,   148,   101,   165,   119,    99,   165,    32,   126,   165,
-      37,    38,    76,   119,   145,   147,   158,    99,   119,   126,
-     165,   126,   128,   120,   165,   120,   119,    99,   124,     0,
-     109,   126,   165,    99,   100,   101,   151,   164,   151,   165,
-     165,   165,   165,    70,    99,    99,    99,   100,   151,   151,
-     165,   165,   164,    64,    65,    66,    67,    68,    70,    75,
-     119,   165,   164,   164,   102,   145,   165,     4,     5,     7,
-       8,   105,   119,   161,   162,   165,   169,   170,   101,    99,
-      99,    29,    43,    44,    45,    46,    47,    48,    50,    53,
-      54,    55,    92,    93,    94,    95,    96,    97,    98,   100,
-     127,   144,   166,   168,    99,   165,    34,   120,    99,    99,
-      99,    24,    51,    52,   119,   165,   119,    35,    45,   130,
-      99,    99,    37,    99,    99,    99,    35,    99,    99,   120,
-      99,   119,   102,   165,    29,    35,    29,    35,    29,    35,
-      29,    35,    56,    58,    60,    62,   149,   119,    29,   166,
-      69,    77,    69,    77,    69,    77,    69,    77,    69,    77,
-      29,    29,    82,    83,   166,   100,   102,   105,   105,   105,
-     105,   104,   105,   100,   104,   104,   100,   102,   145,   170,
-      27,   165,   165,   165,   165,   165,   165,   165,   165,   165,
-     165,   165,   165,   165,   165,   165,   165,   165,   170,    43,
-      44,    45,    46,    47,    48,    50,    53,    54,    55,    92,
-      93,    94,    95,    96,    97,    98,   100,   127,    99,   122,
-      99,    76,   145,   146,   148,   146,   146,    23,    45,    99,
-      29,   165,     9,    87,    99,   112,   113,   114,   115,   165,
-     124,    99,   122,   138,   139,   140,    99,   100,   164,   165,
-     164,   165,   164,   165,   164,   165,    23,    29,   157,    27,
-      57,    59,    61,    63,    71,    72,    73,    74,    78,    79,
-      80,    81,   153,   154,   164,   153,   164,   164,   100,   127,
-     102,   170,   165,   165,   165,   165,   165,   162,   165,   165,
-     166,   100,   127,   165,   127,   165,   165,   165,   165,   165,
-     165,   165,   165,   165,   165,   165,   165,   165,   165,   165,
-     165,   165,   170,    99,   123,   141,   142,   143,    16,   138,
-      99,    99,    99,   165,   165,   138,    71,    73,    80,    81,
-     159,   164,    99,   117,   119,   115,    99,    90,   140,   138,
-     102,   170,    29,    29,    29,    29,   164,   165,   157,   157,
-     157,   157,   164,   164,   157,   164,   164,   170,   102,   127,
-     100,   127,   102,   127,    16,    88,   134,   143,    99,   122,
-      99,    15,    35,    89,   164,   167,   168,   167,   167,   167,
-      99,   120,    99,     9,   127,   164,   164,   164,   164,   164,
-     164,   164,   164,    29,    71,   154,   127,   102,   170,   102,
-      99,   122,    99,   141,   138,    35,   165,    99,    43,    44,
-      46,    47,    48,    50,    53,    54,    55,    92,    93,    94,
-      95,    96,    97,    98,    29,    99,   117,   102,    71,   102,
-     127,   141,   134,    89,   165,    99,   167,   167,   167,   167,
+      70,    71,    72,    73,    75,    76,    77,    78,    79,    82,
+      83,    84,    85,    86,    87,    88,    90,    93,   101,   109,
+     110,   111,   112,   113,   118,   120,   124,   125,   126,   127,
+     131,   133,   134,   135,   137,   138,   139,     9,    16,    18,
+      19,    21,    22,    23,    24,    27,    28,    30,    33,    34,
+      35,    36,    41,    42,    43,    44,    86,    87,    88,    89,
+      93,   119,   120,   121,    10,    11,    14,    15,    58,    60,
+      62,    64,    78,   150,    34,   101,   121,   122,   123,     4,
+       5,     7,     8,    10,    11,    12,    13,    14,    15,    20,
+      29,    51,    58,    60,    62,    64,    78,    83,    97,    98,
+     103,   105,   121,   128,   130,   146,   147,   150,   152,   154,
+     157,   158,   162,   165,   166,   167,   170,   150,   103,   167,
+     121,   101,   167,    34,   128,   167,    39,    40,    78,   121,
+     147,   149,   160,   101,   121,   128,   167,   128,   130,   122,
+     167,   122,   121,   101,   126,     0,   111,   128,   167,   101,
+     102,   103,   153,   166,   153,   153,   153,   167,   167,   167,
+     167,    72,   101,   101,   101,   102,   153,   153,   167,   167,
+     166,    66,    67,    68,    69,    70,    72,    77,   121,   167,
+     166,   166,   104,   147,   167,     4,     5,     7,     8,   107,
+     121,   163,   164,   167,   171,   172,   103,   101,   101,    31,
+      45,    46,    47,    48,    49,    50,    52,    55,    56,    57,
+      94,    95,    96,    97,    98,    99,   100,   102,   129,   146,
+     168,   170,   101,   167,    36,   122,   101,   101,   101,    26,
+      53,    54,   121,   167,   121,    37,    47,   132,   101,   101,
+      39,   101,   101,   101,    37,   101,   101,   122,   101,   121,
+     104,   167,    31,    37,    31,    37,    31,    37,    31,    37,
+      58,    60,    62,    64,   151,   121,    31,   168,    71,    79,
+      71,    79,    71,    79,    71,    79,    71,    79,    31,    31,
+      84,    85,   168,   102,   104,   107,   107,   107,   107,   106,
+     107,   102,   106,   106,   102,   104,   147,   172,    29,   167,
+     167,   167,   167,   167,   167,   167,   167,   167,   167,   167,
+     167,   167,   167,   167,   167,   167,   172,    45,    46,    47,
+      48,    49,    50,    52,    55,    56,    57,    94,    95,    96,
+      97,    98,    99,   100,   102,   129,   101,   124,   101,    78,
+     147,   148,   150,   148,   148,    25,    47,   101,    31,   167,
+       9,    89,   101,   114,   115,   116,   117,   167,   126,   101,
+     124,   140,   141,   142,   101,   102,   166,   167,   166,   167,
+     166,   167,   166,   167,    25,    31,   159,    29,    59,    61,
+      63,    65,    73,    74,    75,    76,    80,    81,    82,    83,
+     155,   156,   166,   155,   166,   166,   102,   129,   104,   172,
+     167,   167,   167,   167,   167,   164,   167,   167,   168,   102,
+     129,   167,   129,   167,   167,   167,   167,   167,   167,   167,
      167,   167,   167,   167,   167,   167,   167,   167,   167,   167,
-     167,   167,    71,   138,    99,   164,   102,   134,    99,    99,
-     138,   167,   138,    89,    89,    99,    99
+     172,   101,   125,   143,   144,   145,    18,   140,   101,   101,
+     101,   167,   167,   140,    73,    75,    82,    83,   161,   166,
+     101,   119,   121,   117,   101,    92,   142,   140,   104,   172,
+      31,    31,    31,    31,   166,   167,   159,   159,   159,   159,
+     166,   166,   159,   166,   166,   172,   104,   129,   102,   129,
+     104,   129,    18,    90,   136,   145,   101,   124,   101,    17,
+      37,    91,   166,   169,   170,   169,   169,   169,   101,   122,
+     101,     9,   129,   166,   166,   166,   166,   166,   166,   166,
+     166,    31,    73,   156,   129,   104,   172,   104,   101,   124,
+     101,   143,   140,    37,   167,   101,    45,    46,    48,    49,
+      50,    52,    55,    56,    57,    94,    95,    96,    97,    98,
+      99,   100,    31,   101,   119,   104,    73,   104,   129,   143,
+     136,    91,   167,   101,   169,   169,   169,   169,   169,   169,
+     169,   169,   169,   169,   169,   169,   169,   169,   169,   169,
+      73,   140,   101,   166,   104,   136,   101,   101,   140,   169,
+     140,    91,    91,   101,   101
 };
 
 /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,   106,   107,   108,   108,   109,   109,   109,   109,   109,
-     109,   110,   111,   112,   113,   113,   114,   114,   115,   115,
-     115,   116,   116,   117,   117,   117,   118,   118,   118,   118,
-     118,   118,   118,   118,   118,   118,   118,   118,   118,   118,
-     118,   118,   118,   118,   118,   118,   118,   118,   118,   118,
-     118,   118,   118,   118,   118,   118,   118,   118,   118,   118,
-     118,   118,   118,   118,   118,   118,   118,   118,   118,   118,
-     118,   118,   118,   119,   119,   119,   119,   119,   119,   119,
-     119,   119,   119,   119,   119,   119,   119,   119,   119,   119,
-     119,   119,   119,   120,   120,   120,   121,   121,   122,   122,
-     123,   123,   123,   123,   123,   123,   124,   124,   124,   125,
-     125,   125,   125,   125,   125,   125,   125,   125,   125,   125,
-     125,   125,   125,   125,   125,   126,   126,   126,   126,   126,
-     126,   126,   126,   126,   126,   127,   127,   128,   128,   128,
-     128,   128,   129,   129,   129,   129,   130,   130,   131,   131,
-     131,   132,   132,   133,   133,   133,   133,   134,   134,   135,
-     135,   135,   135,   136,   136,   137,   138,   138,   139,   139,
-     140,   140,   141,   141,   142,   142,   143,   143,   144,   144,
-     144,   144,   144,   144,   144,   144,   144,   144,   144,   144,
-     144,   144,   144,   145,   146,   146,   147,   147,   148,   148,
-     148,   148,   148,   148,   148,   148,   148,   148,   148,   149,
-     149,   149,   149,   150,   150,   151,   151,   151,   151,   152,
-     152,   152,   152,   152,   153,   153,   153,   153,   153,   154,
-     155,   155,   155,   155,   155,   155,   155,   155,   155,   155,
-     156,   156,   156,   156,   156,   156,   156,   156,   157,   157,
-     158,   158,   159,   159,   159,   159,   159,   160,   160,   160,
-     161,   161,   161,   162,   162,   162,   162,   162,   163,   163,
-     164,   164,   165,   165,   165,   165,   165,   165,   165,   165,
-     165,   165,   165,   165,   165,   165,   165,   165,   165,   165,
-     165,   166,   166,   166,   166,   166,   166,   166,   166,   166,
-     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
+       0,   108,   109,   110,   110,   111,   111,   111,   111,   111,
+     111,   112,   113,   114,   115,   115,   116,   116,   117,   117,
+     117,   118,   118,   119,   119,   119,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   120,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   120,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   120,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   120,   120,   120,   120,   120,
+     120,   120,   120,   120,   120,   121,   121,   121,   121,   121,
+     121,   121,   121,   121,   121,   121,   121,   121,   121,   121,
+     121,   121,   121,   121,   121,   122,   122,   122,   123,   123,
+     124,   124,   125,   125,   125,   125,   125,   125,   126,   126,
+     126,   127,   127,   127,   127,   127,   127,   127,   127,   127,
+     127,   127,   127,   127,   127,   127,   127,   128,   128,   128,
+     128,   128,   128,   128,   128,   128,   128,   129,   129,   130,
+     130,   130,   130,   130,   131,   131,   131,   131,   132,   132,
+     133,   133,   133,   134,   134,   135,   135,   135,   135,   136,
+     136,   137,   137,   137,   137,   138,   138,   139,   140,   140,
+     141,   141,   142,   142,   143,   143,   144,   144,   145,   145,
+     146,   146,   146,   146,   146,   146,   146,   146,   146,   146,
+     146,   146,   146,   146,   146,   147,   148,   148,   149,   149,
+     150,   150,   150,   150,   150,   150,   150,   150,   150,   150,
+     150,   150,   150,   151,   151,   151,   151,   152,   152,   153,
+     153,   153,   153,   154,   154,   154,   154,   154,   155,   155,
+     155,   155,   155,   156,   157,   157,   157,   157,   157,   157,
+     157,   157,   157,   157,   158,   158,   158,   158,   158,   158,
+     158,   158,   159,   159,   160,   160,   161,   161,   161,   161,
+     161,   162,   162,   162,   163,   163,   163,   164,   164,   164,
+     164,   164,   165,   165,   166,   166,   167,   167,   167,   167,
      167,   167,   167,   167,   167,   167,   167,   167,   167,   167,
-     167,   167,   167,   167,   167,   167,   167,   167,   168,   168,
-     169,   169,   170,   170
+     167,   167,   167,   167,   167,   168,   168,   168,   168,   168,
+     168,   168,   168,   168,   168,   168,   168,   168,   168,   168,
+     168,   168,   168,   168,   169,   169,   169,   169,   169,   169,
+     169,   169,   169,   169,   169,   169,   169,   169,   169,   169,
+     169,   169,   170,   170,   171,   171,   172,   172
 };
 
 /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
@@ -2028,31 +2064,31 @@ static const yytype_int8 yyr2[] =
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     0,     1,     2,     1,     3,     1,     2,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
-       3,     3,     3,     3,     3,     3,     5,     3,     3,     2,
-       2,     3,     3,     3,     2,     0,     2,     4,     3,     5,
-       2,     4,     6,     5,     7,     0,     1,     2,     2,     5,
-       4,     3,     5,     5,     5,     5,     1,     1,     3,     3,
-       3,     4,     6,     6,     8,     7,     9,     0,     2,     7,
-      11,    12,     9,     4,     6,     2,     0,     1,     1,     2,
-       1,     1,     0,     1,     1,     2,     1,     1,     1,     1,
-       1,     1,     2,     3,     5,     6,     8,     3,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     2,     2,
-       4,     6,     4,     6,     4,     6,     4,     6,     5,     1,
-       1,     1,     1,     2,     2,     1,     2,     4,     6,     2,
-       4,     4,     1,     1,     1,     1,     5,     2,     2,     2,
+       1,     1,     1,     1,     1,     0,     1,     2,     1,     3,
+       1,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     3,     3,     3,     3,     3,     3,     3,     5,     3,
+       3,     2,     2,     3,     3,     3,     2,     0,     2,     4,
+       3,     5,     2,     4,     6,     5,     7,     0,     1,     2,
+       2,     5,     4,     3,     5,     5,     5,     5,     1,     1,
+       3,     3,     3,     4,     6,     6,     8,     7,     9,     0,
+       2,     7,    11,    12,     9,     4,     6,     2,     0,     1,
+       1,     2,     1,     1,     0,     1,     1,     2,     1,     1,
+       1,     1,     1,     1,     2,     3,     5,     6,     8,     3,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       2,     2,     2,     2,     4,     6,     4,     6,     4,     6,
+       4,     6,     5,     1,     1,     1,     1,     2,     2,     1,
+       2,     4,     6,     2,     4,     4,     1,     1,     1,     1,
+       5,     2,     2,     2,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     6,     6,     6,     6,     6,     4,
+       4,     4,     1,     1,     2,     4,     1,     2,     5,     2,
+       2,     3,     3,     3,     1,     3,     3,     3,     3,     3,
+       3,     3,     2,     2,     1,     1,     1,     1,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       6,     6,     6,     6,     6,     4,     4,     4,     1,     1,
-       2,     4,     1,     2,     5,     2,     2,     3,     3,     3,
-       1,     3,     3,     3,     3,     3,     3,     3,     2,     2,
-       1,     1,     1,     1,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     1,     1,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     1,     1,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     1,     1,     3,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       1,     1,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     3,     3,     4,     4,
-       0,     1,     1,     3
+       3,     3,     4,     4,     0,     1,     1,     3
 };
 
 
@@ -2257,7 +2293,7 @@ yypcontext_expected_tokens (const yypcontext_t *yyctx,
   int yyn = yypact[+*yyctx->yyssp];
   if (!yypact_value_is_default (yyn))
     {
-      /* Start YYX at -YYN if negative to avoid negative indices in
+      /* Start YYX at -YYN if negative to avoid negative indexes in
          YYCHECK.  In other words, skip the first -YYN actions for
          this state because they are default actions.  */
       int yyxbegin = yyn < 0 ? -yyn : 0;
@@ -2320,283 +2356,283 @@ yydestruct (const char *yymsg,
     case YYSYMBOL_tVARID: /* tVARID  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2324 "engines/director/lingo/lingo-gr.cpp"
+#line 2360 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_tSTRING: /* tSTRING  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2330 "engines/director/lingo/lingo-gr.cpp"
+#line 2366 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_tSYMBOL: /* tSYMBOL  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2336 "engines/director/lingo/lingo-gr.cpp"
+#line 2372 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_tENDCLAUSE: /* tENDCLAUSE  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2342 "engines/director/lingo/lingo-gr.cpp"
+#line 2378 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_script: /* script  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2348 "engines/director/lingo/lingo-gr.cpp"
+#line 2384 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_scriptpart: /* scriptpart  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2354 "engines/director/lingo/lingo-gr.cpp"
+#line 2390 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_macro: /* macro  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2360 "engines/director/lingo/lingo-gr.cpp"
+#line 2396 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_factory: /* factory  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2366 "engines/director/lingo/lingo-gr.cpp"
+#line 2402 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_method: /* method  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2372 "engines/director/lingo/lingo-gr.cpp"
+#line 2408 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_methodlistline: /* methodlistline  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2378 "engines/director/lingo/lingo-gr.cpp"
+#line 2414 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_handler: /* handler  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2384 "engines/director/lingo/lingo-gr.cpp"
+#line 2420 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_CMDID: /* CMDID  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2390 "engines/director/lingo/lingo-gr.cpp"
+#line 2426 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_ID: /* ID  */
 #line 201 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).s); }
-#line 2396 "engines/director/lingo/lingo-gr.cpp"
+#line 2432 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_stmt: /* stmt  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2402 "engines/director/lingo/lingo-gr.cpp"
+#line 2438 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_stmt_insideif: /* stmt_insideif  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2408 "engines/director/lingo/lingo-gr.cpp"
+#line 2444 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_stmtoneliner: /* stmtoneliner  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2414 "engines/director/lingo/lingo-gr.cpp"
+#line 2450 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_proc: /* proc  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2420 "engines/director/lingo/lingo-gr.cpp"
+#line 2456 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_asgn: /* asgn  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2426 "engines/director/lingo/lingo-gr.cpp"
+#line 2462 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_definevars: /* definevars  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2432 "engines/director/lingo/lingo-gr.cpp"
+#line 2468 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_ifstmt: /* ifstmt  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2438 "engines/director/lingo/lingo-gr.cpp"
+#line 2474 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_ifelsestmt: /* ifelsestmt  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2444 "engines/director/lingo/lingo-gr.cpp"
+#line 2480 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_loop: /* loop  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2450 "engines/director/lingo/lingo-gr.cpp"
+#line 2486 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_tell: /* tell  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2456 "engines/director/lingo/lingo-gr.cpp"
+#line 2492 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_when: /* when  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2462 "engines/director/lingo/lingo-gr.cpp"
+#line 2498 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_stmtlistline: /* stmtlistline  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2468 "engines/director/lingo/lingo-gr.cpp"
+#line 2504 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_stmtlistline_insideif: /* stmtlistline_insideif  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2474 "engines/director/lingo/lingo-gr.cpp"
+#line 2510 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_simpleexpr_nounarymath: /* simpleexpr_nounarymath  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2480 "engines/director/lingo/lingo-gr.cpp"
+#line 2516 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_var: /* var  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2486 "engines/director/lingo/lingo-gr.cpp"
+#line 2522 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_varorchunk: /* varorchunk  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2492 "engines/director/lingo/lingo-gr.cpp"
+#line 2528 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_varorthe: /* varorthe  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2498 "engines/director/lingo/lingo-gr.cpp"
+#line 2534 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_chunk: /* chunk  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2504 "engines/director/lingo/lingo-gr.cpp"
+#line 2540 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_object: /* object  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2510 "engines/director/lingo/lingo-gr.cpp"
+#line 2546 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_the: /* the  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2516 "engines/director/lingo/lingo-gr.cpp"
+#line 2552 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_theobj: /* theobj  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2522 "engines/director/lingo/lingo-gr.cpp"
+#line 2558 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_menu: /* menu  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2528 "engines/director/lingo/lingo-gr.cpp"
+#line 2564 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_thedatetime: /* thedatetime  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2534 "engines/director/lingo/lingo-gr.cpp"
+#line 2570 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_thenumberof: /* thenumberof  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2540 "engines/director/lingo/lingo-gr.cpp"
+#line 2576 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_writablethe: /* writablethe  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2546 "engines/director/lingo/lingo-gr.cpp"
+#line 2582 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_writabletheobj: /* writabletheobj  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2552 "engines/director/lingo/lingo-gr.cpp"
+#line 2588 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_list: /* list  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2558 "engines/director/lingo/lingo-gr.cpp"
+#line 2594 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_proppair: /* proppair  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2564 "engines/director/lingo/lingo-gr.cpp"
+#line 2600 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_unarymath: /* unarymath  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2570 "engines/director/lingo/lingo-gr.cpp"
+#line 2606 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_simpleexpr: /* simpleexpr  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2576 "engines/director/lingo/lingo-gr.cpp"
+#line 2612 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_expr: /* expr  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2582 "engines/director/lingo/lingo-gr.cpp"
+#line 2618 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_expr_nounarymath: /* expr_nounarymath  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2588 "engines/director/lingo/lingo-gr.cpp"
+#line 2624 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_expr_noeq: /* expr_noeq  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2594 "engines/director/lingo/lingo-gr.cpp"
+#line 2630 "engines/director/lingo/lingo-gr.cpp"
         break;
 
     case YYSYMBOL_sprite: /* sprite  */
 #line 202 "engines/director/lingo/lingo-gr.y"
             { delete ((*yyvaluep).node); }
-#line 2600 "engines/director/lingo/lingo-gr.cpp"
+#line 2636 "engines/director/lingo/lingo-gr.cpp"
         break;
 
       default:
@@ -2866,7 +2902,7 @@ yyreduce:
   case 2: /* script: scriptpartlist  */
 #line 208 "engines/director/lingo/lingo-gr.y"
                                                         { g_lingo->_compiler->_assemblyAST = Common::SharedPtr<Node>(new ScriptNode((yyvsp[0].nodelist))); (yyval.node) = nullptr; }
-#line 2870 "engines/director/lingo/lingo-gr.cpp"
+#line 2906 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 3: /* scriptpartlist: scriptpart  */
@@ -2877,7 +2913,7 @@ yyreduce:
 			list->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = list; }
-#line 2881 "engines/director/lingo/lingo-gr.cpp"
+#line 2917 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 4: /* scriptpartlist: scriptpartlist scriptpart  */
@@ -2887,43 +2923,43 @@ yyreduce:
 			(yyvsp[-1].nodelist)->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 2891 "engines/director/lingo/lingo-gr.cpp"
+#line 2927 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 5: /* scriptpart: '\n'  */
 #line 223 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = nullptr; }
-#line 2897 "engines/director/lingo/lingo-gr.cpp"
+#line 2933 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 10: /* scriptpart: tENDCLAUSE endargdef '\n'  */
 #line 228 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = nullptr; delete (yyvsp[-2].s); }
-#line 2903 "engines/director/lingo/lingo-gr.cpp"
+#line 2939 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 11: /* macro: tMACRO ID idlist '\n' stmtlist  */
 #line 257 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new HandlerNode((yyvsp[-3].s), (yyvsp[-2].idlist), (yyvsp[0].nodelist)); }
-#line 2909 "engines/director/lingo/lingo-gr.cpp"
+#line 2945 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 12: /* factory: tFACTORY ID '\n' methodlist  */
 #line 261 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new FactoryNode((yyvsp[-2].s), (yyvsp[0].nodelist)); }
-#line 2915 "engines/director/lingo/lingo-gr.cpp"
+#line 2951 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 13: /* method: tMETHOD ID idlist '\n' stmtlist  */
 #line 263 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new HandlerNode((yyvsp[-3].s), (yyvsp[-2].idlist), (yyvsp[0].nodelist)); }
-#line 2921 "engines/director/lingo/lingo-gr.cpp"
+#line 2957 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 14: /* methodlist: %empty  */
 #line 265 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.nodelist) = new NodeList; }
-#line 2927 "engines/director/lingo/lingo-gr.cpp"
+#line 2963 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 16: /* nonemptymethodlist: methodlistline  */
@@ -2934,7 +2970,7 @@ yyreduce:
 			list->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = list; }
-#line 2938 "engines/director/lingo/lingo-gr.cpp"
+#line 2974 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 17: /* nonemptymethodlist: nonemptymethodlist methodlistline  */
@@ -2944,19 +2980,19 @@ yyreduce:
 			(yyvsp[-1].nodelist)->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 2948 "engines/director/lingo/lingo-gr.cpp"
+#line 2984 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 18: /* methodlistline: '\n'  */
 #line 282 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = nullptr; }
-#line 2954 "engines/director/lingo/lingo-gr.cpp"
+#line 2990 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 20: /* methodlistline: tENDCLAUSE endargdef '\n'  */
 #line 284 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = nullptr; delete (yyvsp[-2].s); }
-#line 2960 "engines/director/lingo/lingo-gr.cpp"
+#line 2996 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 21: /* handler: tON ID idlist '\n' stmtlist tENDCLAUSE endargdef '\n'  */
@@ -2965,793 +3001,805 @@ yyreduce:
 		(yyval.node) = new HandlerNode((yyvsp[-6].s), (yyvsp[-5].idlist), (yyvsp[-3].nodelist));
 		checkEnd((yyvsp[-2].s), (yyvsp[-6].s), false);
 		delete (yyvsp[-2].s); }
-#line 2969 "engines/director/lingo/lingo-gr.cpp"
+#line 3005 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 22: /* handler: tON ID idlist '\n' stmtlist  */
 #line 293 "engines/director/lingo/lingo-gr.y"
                                       {	// D4. No 'end' clause
 		(yyval.node) = new HandlerNode((yyvsp[-3].s), (yyvsp[-2].idlist), (yyvsp[0].nodelist)); }
-#line 2976 "engines/director/lingo/lingo-gr.cpp"
+#line 3012 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 24: /* endargdef: ID  */
 #line 298 "engines/director/lingo/lingo-gr.y"
                                                         { delete (yyvsp[0].s); }
-#line 2982 "engines/director/lingo/lingo-gr.cpp"
+#line 3018 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 25: /* endargdef: endargdef ',' ID  */
 #line 299 "engines/director/lingo/lingo-gr.y"
                                                 { delete (yyvsp[0].s); }
-#line 2988 "engines/director/lingo/lingo-gr.cpp"
+#line 3024 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 27: /* CMDID: tABBREVIATED  */
 #line 307 "engines/director/lingo/lingo-gr.y"
                         { (yyval.s) = new Common::String("abbreviated"); }
-#line 2994 "engines/director/lingo/lingo-gr.cpp"
+#line 3030 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 28: /* CMDID: tABBREV  */
 #line 308 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("abbrev"); }
-#line 3000 "engines/director/lingo/lingo-gr.cpp"
+#line 3036 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 29: /* CMDID: tABBR  */
 #line 309 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("abbr"); }
-#line 3006 "engines/director/lingo/lingo-gr.cpp"
+#line 3042 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 30: /* CMDID: tAFTER  */
 #line 310 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("after"); }
-#line 3012 "engines/director/lingo/lingo-gr.cpp"
+#line 3048 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 31: /* CMDID: tBEFORE  */
 #line 311 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("before"); }
-#line 3018 "engines/director/lingo/lingo-gr.cpp"
+#line 3054 "engines/director/lingo/lingo-gr.cpp"
     break;
 
   case 32: /* CMDID: tCAST  */
 #line 312 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("cast"); }
-#line 3024 "engines/director/lingo/lingo-gr.cpp"
+#line 3060 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 33: /* CMDID: tCHAR  */
+  case 33: /* CMDID: tCASTLIB  */
 #line 313 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("char"); }
-#line 3030 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("castLib"); }
+#line 3066 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 34: /* CMDID: tCHARS  */
+  case 34: /* CMDID: tCHAR  */
 #line 314 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("chars"); }
-#line 3036 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("char"); }
+#line 3072 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 35: /* CMDID: tDATE  */
+  case 35: /* CMDID: tCHARS  */
 #line 315 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("date"); }
-#line 3042 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("chars"); }
+#line 3078 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 36: /* CMDID: tDELETE  */
+  case 36: /* CMDID: tDATE  */
 #line 316 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("delete"); }
-#line 3048 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("date"); }
+#line 3084 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 37: /* CMDID: tDOWN  */
+  case 37: /* CMDID: tDELETE  */
 #line 317 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("down"); }
-#line 3054 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("delete"); }
+#line 3090 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 38: /* CMDID: tFIELD  */
+  case 38: /* CMDID: tDOWN  */
 #line 318 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("field"); }
-#line 3060 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("down"); }
+#line 3096 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 39: /* CMDID: tFRAME  */
+  case 39: /* CMDID: tFIELD  */
 #line 319 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("frame"); }
-#line 3066 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("field"); }
+#line 3102 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 40: /* CMDID: tHILITE  */
+  case 40: /* CMDID: tFRAME  */
 #line 320 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("hilite"); }
-#line 3072 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("frame"); }
+#line 3108 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 41: /* CMDID: tIN  */
+  case 41: /* CMDID: tHILITE  */
 #line 321 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("in"); }
-#line 3078 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("hilite"); }
+#line 3114 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 42: /* CMDID: tINTERSECTS  */
+  case 42: /* CMDID: tIN  */
 #line 322 "engines/director/lingo/lingo-gr.y"
-                        { (yyval.s) = new Common::String("intersects"); }
-#line 3084 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("in"); }
+#line 3120 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 43: /* CMDID: tINTO  */
+  case 43: /* CMDID: tINTERSECTS  */
 #line 323 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("into"); }
-#line 3090 "engines/director/lingo/lingo-gr.cpp"
+                        { (yyval.s) = new Common::String("intersects"); }
+#line 3126 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 44: /* CMDID: tITEM  */
+  case 44: /* CMDID: tINTO  */
 #line 324 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("item"); }
-#line 3096 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("into"); }
+#line 3132 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 45: /* CMDID: tITEMS  */
+  case 45: /* CMDID: tITEM  */
 #line 325 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("items"); }
-#line 3102 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("item"); }
+#line 3138 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 46: /* CMDID: tLAST  */
+  case 46: /* CMDID: tITEMS  */
 #line 326 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("last"); }
-#line 3108 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("items"); }
+#line 3144 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 47: /* CMDID: tLINE  */
+  case 47: /* CMDID: tLAST  */
 #line 327 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("line"); }
-#line 3114 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("last"); }
+#line 3150 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 48: /* CMDID: tLINES  */
+  case 48: /* CMDID: tLINE  */
 #line 328 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("lines"); }
-#line 3120 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("line"); }
+#line 3156 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 49: /* CMDID: tLONG  */
+  case 49: /* CMDID: tLINES  */
 #line 329 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("long"); }
-#line 3126 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("lines"); }
+#line 3162 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 50: /* CMDID: tMENU  */
+  case 50: /* CMDID: tLONG  */
 #line 330 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("menu"); }
-#line 3132 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("long"); }
+#line 3168 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 51: /* CMDID: tMENUITEM  */
+  case 51: /* CMDID: tMEMBER  */
 #line 331 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("menuItem"); }
-#line 3138 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("member"); }
+#line 3174 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 52: /* CMDID: tMENUITEMS  */
+  case 52: /* CMDID: tMENU  */
 #line 332 "engines/director/lingo/lingo-gr.y"
-                        { (yyval.s) = new Common::String("menuItems"); }
-#line 3144 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("menu"); }
+#line 3180 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 53: /* CMDID: tMOVIE  */
+  case 53: /* CMDID: tMENUITEM  */
 #line 333 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("movie"); }
-#line 3150 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("menuItem"); }
+#line 3186 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 54: /* CMDID: tNEXT  */
+  case 54: /* CMDID: tMENUITEMS  */
 #line 334 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("next"); }
-#line 3156 "engines/director/lingo/lingo-gr.cpp"
+                        { (yyval.s) = new Common::String("menuItems"); }
+#line 3192 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 55: /* CMDID: tNUMBER  */
+  case 55: /* CMDID: tMOVIE  */
 #line 335 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("number"); }
-#line 3162 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("movie"); }
+#line 3198 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 56: /* CMDID: tOF  */
+  case 56: /* CMDID: tNEXT  */
 #line 336 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("of"); }
-#line 3168 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("next"); }
+#line 3204 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 57: /* CMDID: tPREVIOUS  */
+  case 57: /* CMDID: tNUMBER  */
 #line 337 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("previous"); }
-#line 3174 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("number"); }
+#line 3210 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 58: /* CMDID: tREPEAT  */
+  case 58: /* CMDID: tOF  */
 #line 338 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("repeat"); }
-#line 3180 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("of"); }
+#line 3216 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 59: /* CMDID: tSCRIPT  */
+  case 59: /* CMDID: tPREVIOUS  */
 #line 339 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("script"); }
-#line 3186 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("previous"); }
+#line 3222 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 60: /* CMDID: tASSERTERROR  */
+  case 60: /* CMDID: tREPEAT  */
 #line 340 "engines/director/lingo/lingo-gr.y"
-                        { (yyval.s) = new Common::String("scummvmAssertError"); }
-#line 3192 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("repeat"); }
+#line 3228 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 61: /* CMDID: tSHORT  */
+  case 61: /* CMDID: tSCRIPT  */
 #line 341 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("short"); }
-#line 3198 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("script"); }
+#line 3234 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 62: /* CMDID: tSOUND  */
+  case 62: /* CMDID: tASSERTERROR  */
 #line 342 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("sound"); }
-#line 3204 "engines/director/lingo/lingo-gr.cpp"
+                        { (yyval.s) = new Common::String("scummvmAssertError"); }
+#line 3240 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 63: /* CMDID: tSPRITE  */
+  case 63: /* CMDID: tSHORT  */
 #line 343 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("sprite"); }
-#line 3210 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("short"); }
+#line 3246 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 64: /* CMDID: tTHE  */
+  case 64: /* CMDID: tSOUND  */
 #line 344 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("the"); }
-#line 3216 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("sound"); }
+#line 3252 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 65: /* CMDID: tTIME  */
+  case 65: /* CMDID: tSPRITE  */
 #line 345 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("time"); }
-#line 3222 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("sprite"); }
+#line 3258 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 66: /* CMDID: tTO  */
+  case 66: /* CMDID: tTHE  */
 #line 346 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("to"); }
-#line 3228 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("the"); }
+#line 3264 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 67: /* CMDID: tWHILE  */
+  case 67: /* CMDID: tTIME  */
 #line 347 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("while"); }
-#line 3234 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("time"); }
+#line 3270 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 68: /* CMDID: tWINDOW  */
+  case 68: /* CMDID: tTO  */
 #line 348 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("window"); }
-#line 3240 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("to"); }
+#line 3276 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 69: /* CMDID: tWITH  */
+  case 69: /* CMDID: tWHILE  */
 #line 349 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("with"); }
-#line 3246 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("while"); }
+#line 3282 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 70: /* CMDID: tWITHIN  */
+  case 70: /* CMDID: tWINDOW  */
 #line 350 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("within"); }
-#line 3252 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("window"); }
+#line 3288 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 71: /* CMDID: tWORD  */
+  case 71: /* CMDID: tWITH  */
 #line 351 "engines/director/lingo/lingo-gr.y"
-                                { (yyval.s) = new Common::String("word"); }
-#line 3258 "engines/director/lingo/lingo-gr.cpp"
+                                { (yyval.s) = new Common::String("with"); }
+#line 3294 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 72: /* CMDID: tWORDS  */
+  case 72: /* CMDID: tWITHIN  */
 #line 352 "engines/director/lingo/lingo-gr.y"
+                                { (yyval.s) = new Common::String("within"); }
+#line 3300 "engines/director/lingo/lingo-gr.cpp"
+    break;
+
+  case 73: /* CMDID: tWORD  */
+#line 353 "engines/director/lingo/lingo-gr.y"
+                                { (yyval.s) = new Common::String("word"); }
+#line 3306 "engines/director/lingo/lingo-gr.cpp"
+    break;
+
+  case 74: /* CMDID: tWORDS  */
+#line 354 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("words"); }
-#line 3264 "engines/director/lingo/lingo-gr.cpp"
+#line 3312 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 74: /* ID: tELSE  */
-#line 356 "engines/director/lingo/lingo-gr.y"
+  case 76: /* ID: tELSE  */
+#line 358 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("else"); }
-#line 3270 "engines/director/lingo/lingo-gr.cpp"
+#line 3318 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 75: /* ID: tENDCLAUSE  */
-#line 357 "engines/director/lingo/lingo-gr.y"
+  case 77: /* ID: tENDCLAUSE  */
+#line 359 "engines/director/lingo/lingo-gr.y"
                         { (yyval.s) = new Common::String("end"); delete (yyvsp[0].s); }
-#line 3276 "engines/director/lingo/lingo-gr.cpp"
+#line 3324 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 76: /* ID: tEXIT  */
-#line 358 "engines/director/lingo/lingo-gr.y"
+  case 78: /* ID: tEXIT  */
+#line 360 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("exit"); }
-#line 3282 "engines/director/lingo/lingo-gr.cpp"
+#line 3330 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 77: /* ID: tFACTORY  */
-#line 359 "engines/director/lingo/lingo-gr.y"
+  case 79: /* ID: tFACTORY  */
+#line 361 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("factory"); }
-#line 3288 "engines/director/lingo/lingo-gr.cpp"
+#line 3336 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 78: /* ID: tGLOBAL  */
-#line 360 "engines/director/lingo/lingo-gr.y"
+  case 80: /* ID: tGLOBAL  */
+#line 362 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("global"); }
-#line 3294 "engines/director/lingo/lingo-gr.cpp"
+#line 3342 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 79: /* ID: tGO  */
-#line 361 "engines/director/lingo/lingo-gr.y"
+  case 81: /* ID: tGO  */
+#line 363 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("go"); }
-#line 3300 "engines/director/lingo/lingo-gr.cpp"
+#line 3348 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 80: /* ID: tIF  */
-#line 362 "engines/director/lingo/lingo-gr.y"
+  case 82: /* ID: tIF  */
+#line 364 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("if"); }
-#line 3306 "engines/director/lingo/lingo-gr.cpp"
+#line 3354 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 81: /* ID: tINSTANCE  */
-#line 363 "engines/director/lingo/lingo-gr.y"
+  case 83: /* ID: tINSTANCE  */
+#line 365 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("instance"); }
-#line 3312 "engines/director/lingo/lingo-gr.cpp"
+#line 3360 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 82: /* ID: tMACRO  */
-#line 364 "engines/director/lingo/lingo-gr.y"
+  case 84: /* ID: tMACRO  */
+#line 366 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("macro"); }
-#line 3318 "engines/director/lingo/lingo-gr.cpp"
+#line 3366 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 83: /* ID: tMETHOD  */
-#line 365 "engines/director/lingo/lingo-gr.y"
+  case 85: /* ID: tMETHOD  */
+#line 367 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("method"); }
-#line 3324 "engines/director/lingo/lingo-gr.cpp"
+#line 3372 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 84: /* ID: tON  */
-#line 366 "engines/director/lingo/lingo-gr.y"
+  case 86: /* ID: tON  */
+#line 368 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("on"); }
-#line 3330 "engines/director/lingo/lingo-gr.cpp"
+#line 3378 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 85: /* ID: tOPEN  */
-#line 367 "engines/director/lingo/lingo-gr.y"
+  case 87: /* ID: tOPEN  */
+#line 369 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("open"); }
-#line 3336 "engines/director/lingo/lingo-gr.cpp"
+#line 3384 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 86: /* ID: tPLAY  */
-#line 368 "engines/director/lingo/lingo-gr.y"
+  case 88: /* ID: tPLAY  */
+#line 370 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("play"); }
-#line 3342 "engines/director/lingo/lingo-gr.cpp"
+#line 3390 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 87: /* ID: tPROPERTY  */
-#line 369 "engines/director/lingo/lingo-gr.y"
+  case 89: /* ID: tPROPERTY  */
+#line 371 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("property"); }
-#line 3348 "engines/director/lingo/lingo-gr.cpp"
+#line 3396 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 88: /* ID: tPUT  */
-#line 370 "engines/director/lingo/lingo-gr.y"
+  case 90: /* ID: tPUT  */
+#line 372 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("put"); }
-#line 3354 "engines/director/lingo/lingo-gr.cpp"
+#line 3402 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 89: /* ID: tRETURN  */
-#line 371 "engines/director/lingo/lingo-gr.y"
+  case 91: /* ID: tRETURN  */
+#line 373 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("return"); }
-#line 3360 "engines/director/lingo/lingo-gr.cpp"
+#line 3408 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 90: /* ID: tSET  */
-#line 372 "engines/director/lingo/lingo-gr.y"
+  case 92: /* ID: tSET  */
+#line 374 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("set"); }
-#line 3366 "engines/director/lingo/lingo-gr.cpp"
+#line 3414 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 91: /* ID: tTELL  */
-#line 373 "engines/director/lingo/lingo-gr.y"
+  case 93: /* ID: tTELL  */
+#line 375 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("tell"); }
-#line 3372 "engines/director/lingo/lingo-gr.cpp"
+#line 3420 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 92: /* ID: tTHEN  */
-#line 374 "engines/director/lingo/lingo-gr.y"
+  case 94: /* ID: tTHEN  */
+#line 376 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.s) = new Common::String("then"); }
-#line 3378 "engines/director/lingo/lingo-gr.cpp"
+#line 3426 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 93: /* idlist: %empty  */
-#line 377 "engines/director/lingo/lingo-gr.y"
+  case 95: /* idlist: %empty  */
+#line 379 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.idlist) = new IDList; }
-#line 3384 "engines/director/lingo/lingo-gr.cpp"
+#line 3432 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 96: /* nonemptyidlist: ID  */
-#line 382 "engines/director/lingo/lingo-gr.y"
+  case 98: /* nonemptyidlist: ID  */
+#line 384 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		Common::Array<Common::String *> *list = new IDList;
 		list->push_back((yyvsp[0].s));
 		(yyval.idlist) = list; }
-#line 3393 "engines/director/lingo/lingo-gr.cpp"
+#line 3441 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 97: /* nonemptyidlist: nonemptyidlist ',' ID  */
-#line 386 "engines/director/lingo/lingo-gr.y"
+  case 99: /* nonemptyidlist: nonemptyidlist ',' ID  */
+#line 388 "engines/director/lingo/lingo-gr.y"
                                                         {
 		(yyvsp[-2].idlist)->push_back((yyvsp[0].s));
 		(yyval.idlist) = (yyvsp[-2].idlist); }
-#line 3401 "engines/director/lingo/lingo-gr.cpp"
+#line 3449 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 99: /* stmt: tENDIF '\n'  */
-#line 397 "engines/director/lingo/lingo-gr.y"
+  case 101: /* stmt: tENDIF '\n'  */
+#line 399 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = nullptr; }
-#line 3407 "engines/director/lingo/lingo-gr.cpp"
+#line 3455 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 109: /* proc: CMDID cmdargs '\n'  */
-#line 413 "engines/director/lingo/lingo-gr.y"
+  case 111: /* proc: CMDID cmdargs '\n'  */
+#line 415 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new CmdNode((yyvsp[-2].s), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3413 "engines/director/lingo/lingo-gr.cpp"
+#line 3461 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 110: /* proc: tPUT cmdargs '\n'  */
-#line 414 "engines/director/lingo/lingo-gr.y"
+  case 112: /* proc: tPUT cmdargs '\n'  */
+#line 416 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new CmdNode(new Common::String("put"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3419 "engines/director/lingo/lingo-gr.cpp"
+#line 3467 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 111: /* proc: tGO cmdargs '\n'  */
-#line 415 "engines/director/lingo/lingo-gr.y"
+  case 113: /* proc: tGO cmdargs '\n'  */
+#line 417 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3425 "engines/director/lingo/lingo-gr.cpp"
+#line 3473 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 112: /* proc: tGO frameargs '\n'  */
-#line 416 "engines/director/lingo/lingo-gr.y"
+  case 114: /* proc: tGO frameargs '\n'  */
+#line 418 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new CmdNode(new Common::String("go"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3431 "engines/director/lingo/lingo-gr.cpp"
+#line 3479 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 113: /* proc: tPLAY cmdargs '\n'  */
-#line 417 "engines/director/lingo/lingo-gr.y"
+  case 115: /* proc: tPLAY cmdargs '\n'  */
+#line 419 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3437 "engines/director/lingo/lingo-gr.cpp"
+#line 3485 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 114: /* proc: tPLAY frameargs '\n'  */
-#line 418 "engines/director/lingo/lingo-gr.y"
+  case 116: /* proc: tPLAY frameargs '\n'  */
+#line 420 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new CmdNode(new Common::String("play"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3443 "engines/director/lingo/lingo-gr.cpp"
+#line 3491 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 115: /* proc: tOPEN cmdargs '\n'  */
-#line 419 "engines/director/lingo/lingo-gr.y"
+  case 117: /* proc: tOPEN cmdargs '\n'  */
+#line 421 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new CmdNode(new Common::String("open"), (yyvsp[-1].nodelist), g_lingo->_compiler->_linenumber - 1); }
-#line 3449 "engines/director/lingo/lingo-gr.cpp"
+#line 3497 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 116: /* proc: tOPEN expr tWITH expr '\n'  */
-#line 420 "engines/director/lingo/lingo-gr.y"
+  case 118: /* proc: tOPEN expr tWITH expr '\n'  */
+#line 422 "engines/director/lingo/lingo-gr.y"
                                                  {
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-3].node));
 		args->push_back((yyvsp[-1].node));
 		(yyval.node) = new CmdNode(new Common::String("open"), args, g_lingo->_compiler->_linenumber - 1); }
-#line 3459 "engines/director/lingo/lingo-gr.cpp"
+#line 3507 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 117: /* proc: tNEXT tREPEAT '\n'  */
-#line 425 "engines/director/lingo/lingo-gr.y"
+  case 119: /* proc: tNEXT tREPEAT '\n'  */
+#line 427 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new NextRepeatNode(); }
-#line 3465 "engines/director/lingo/lingo-gr.cpp"
+#line 3513 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 118: /* proc: tEXIT tREPEAT '\n'  */
-#line 426 "engines/director/lingo/lingo-gr.y"
+  case 120: /* proc: tEXIT tREPEAT '\n'  */
+#line 428 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new ExitRepeatNode(); }
-#line 3471 "engines/director/lingo/lingo-gr.cpp"
+#line 3519 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 119: /* proc: tEXIT '\n'  */
-#line 427 "engines/director/lingo/lingo-gr.y"
+  case 121: /* proc: tEXIT '\n'  */
+#line 429 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new ExitNode(); }
-#line 3477 "engines/director/lingo/lingo-gr.cpp"
+#line 3525 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 120: /* proc: tRETURN '\n'  */
-#line 428 "engines/director/lingo/lingo-gr.y"
+  case 122: /* proc: tRETURN '\n'  */
+#line 430 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new ReturnNode(nullptr); }
-#line 3483 "engines/director/lingo/lingo-gr.cpp"
+#line 3531 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 121: /* proc: tRETURN expr '\n'  */
-#line 429 "engines/director/lingo/lingo-gr.y"
+  case 123: /* proc: tRETURN expr '\n'  */
+#line 431 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new ReturnNode((yyvsp[-1].node)); }
-#line 3489 "engines/director/lingo/lingo-gr.cpp"
+#line 3537 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 122: /* proc: tDELETE chunk '\n'  */
-#line 430 "engines/director/lingo/lingo-gr.y"
+  case 124: /* proc: tDELETE chunk '\n'  */
+#line 432 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new DeleteNode((yyvsp[-1].node)); }
-#line 3495 "engines/director/lingo/lingo-gr.cpp"
+#line 3543 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 123: /* proc: tHILITE chunk '\n'  */
-#line 431 "engines/director/lingo/lingo-gr.y"
+  case 125: /* proc: tHILITE chunk '\n'  */
+#line 433 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new HiliteNode((yyvsp[-1].node)); }
-#line 3501 "engines/director/lingo/lingo-gr.cpp"
+#line 3549 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 124: /* proc: tASSERTERROR stmtoneliner  */
-#line 432 "engines/director/lingo/lingo-gr.y"
+  case 126: /* proc: tASSERTERROR stmtoneliner  */
+#line 434 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new AssertErrorNode((yyvsp[0].node)); }
-#line 3507 "engines/director/lingo/lingo-gr.cpp"
+#line 3555 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 125: /* cmdargs: %empty  */
-#line 435 "engines/director/lingo/lingo-gr.y"
+  case 127: /* cmdargs: %empty  */
+#line 437 "engines/director/lingo/lingo-gr.y"
                                                                                         {
 		// This matches `cmd`
 		(yyval.nodelist) = new NodeList; }
-#line 3515 "engines/director/lingo/lingo-gr.cpp"
+#line 3563 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 126: /* cmdargs: expr trailingcomma  */
-#line 438 "engines/director/lingo/lingo-gr.y"
+  case 128: /* cmdargs: expr trailingcomma  */
+#line 440 "engines/director/lingo/lingo-gr.y"
                                                                                         {
 		// This matches `cmd arg` and `cmd(arg)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-1].node));
 		(yyval.nodelist) = args; }
-#line 3525 "engines/director/lingo/lingo-gr.cpp"
+#line 3573 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 127: /* cmdargs: expr ',' nonemptyexprlist trailingcomma  */
-#line 443 "engines/director/lingo/lingo-gr.y"
+  case 129: /* cmdargs: expr ',' nonemptyexprlist trailingcomma  */
+#line 445 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `cmd arg, ...)
 		(yyvsp[-1].nodelist)->insert_at(0, (yyvsp[-3].node));
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 3534 "engines/director/lingo/lingo-gr.cpp"
+#line 3582 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 128: /* cmdargs: expr expr_nounarymath trailingcomma  */
-#line 447 "engines/director/lingo/lingo-gr.y"
+  case 130: /* cmdargs: expr expr_nounarymath trailingcomma  */
+#line 449 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		// This matches `cmd arg arg`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-2].node));
 		args->push_back((yyvsp[-1].node));
 		(yyval.nodelist) = args; }
-#line 3545 "engines/director/lingo/lingo-gr.cpp"
+#line 3593 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 129: /* cmdargs: expr expr_nounarymath ',' nonemptyexprlist trailingcomma  */
-#line 453 "engines/director/lingo/lingo-gr.y"
+  case 131: /* cmdargs: expr expr_nounarymath ',' nonemptyexprlist trailingcomma  */
+#line 455 "engines/director/lingo/lingo-gr.y"
                                                                                 {
 		// This matches `cmd arg arg, ...`
 		(yyvsp[-1].nodelist)->insert_at(0, (yyvsp[-3].node));
 		(yyvsp[-1].nodelist)->insert_at(0, (yyvsp[-4].node));
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 3555 "engines/director/lingo/lingo-gr.cpp"
+#line 3603 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 130: /* cmdargs: '(' ')'  */
-#line 458 "engines/director/lingo/lingo-gr.y"
+  case 132: /* cmdargs: '(' ')'  */
+#line 460 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		// This matches `cmd()`
 		(yyval.nodelist) = new NodeList; }
-#line 3563 "engines/director/lingo/lingo-gr.cpp"
+#line 3611 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 131: /* cmdargs: '(' expr ',' ')'  */
-#line 461 "engines/director/lingo/lingo-gr.y"
+  case 133: /* cmdargs: '(' expr ',' ')'  */
+#line 463 "engines/director/lingo/lingo-gr.y"
                            {
 		// This matches `cmd(arg,)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-2].node));
 		(yyval.nodelist) = args; }
-#line 3573 "engines/director/lingo/lingo-gr.cpp"
+#line 3621 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 132: /* cmdargs: '(' expr ',' nonemptyexprlist trailingcomma ')'  */
-#line 466 "engines/director/lingo/lingo-gr.y"
+  case 134: /* cmdargs: '(' expr ',' nonemptyexprlist trailingcomma ')'  */
+#line 468 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `cmd(arg, ...)`
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-4].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 3582 "engines/director/lingo/lingo-gr.cpp"
+#line 3630 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 133: /* cmdargs: '(' var expr_nounarymath trailingcomma ')'  */
-#line 470 "engines/director/lingo/lingo-gr.y"
+  case 135: /* cmdargs: '(' var expr_nounarymath trailingcomma ')'  */
+#line 472 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `obj(method arg)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-3].node));
 		args->push_back((yyvsp[-2].node));
 		(yyval.nodelist) = args; }
-#line 3593 "engines/director/lingo/lingo-gr.cpp"
+#line 3641 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 134: /* cmdargs: '(' var expr_nounarymath ',' nonemptyexprlist trailingcomma ')'  */
-#line 476 "engines/director/lingo/lingo-gr.y"
+  case 136: /* cmdargs: '(' var expr_nounarymath ',' nonemptyexprlist trailingcomma ')'  */
+#line 478 "engines/director/lingo/lingo-gr.y"
                                                                                         {
 		// This matches `obj(method arg, ...)`
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-4].node));
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-5].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 3603 "engines/director/lingo/lingo-gr.cpp"
+#line 3651 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 137: /* frameargs: tFRAME expr  */
-#line 489 "engines/director/lingo/lingo-gr.y"
+  case 139: /* frameargs: tFRAME expr  */
+#line 491 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		// This matches `play frame arg`
 		NodeList *args = new NodeList;
 		args->push_back(new FrameNode((yyvsp[0].node)));
 		(yyval.nodelist) = args; }
-#line 3613 "engines/director/lingo/lingo-gr.cpp"
+#line 3661 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 138: /* frameargs: tMOVIE expr  */
-#line 494 "engines/director/lingo/lingo-gr.y"
+  case 140: /* frameargs: tMOVIE expr  */
+#line 496 "engines/director/lingo/lingo-gr.y"
                                                                                 {
 		// This matches `play movie arg`
 		NodeList *args = new NodeList;
 		args->push_back(new IntNode(1));
 		args->push_back(new MovieNode((yyvsp[0].node)));
 		(yyval.nodelist) = args; }
-#line 3624 "engines/director/lingo/lingo-gr.cpp"
+#line 3672 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 139: /* frameargs: tFRAME expr tOF tMOVIE expr  */
-#line 500 "engines/director/lingo/lingo-gr.y"
+  case 141: /* frameargs: tFRAME expr tOF tMOVIE expr  */
+#line 502 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `play frame arg of movie arg`
 		NodeList *args = new NodeList;
 		args->push_back(new FrameNode((yyvsp[-3].node)));
 		args->push_back(new MovieNode((yyvsp[0].node)));
 		(yyval.nodelist) = args; }
-#line 3635 "engines/director/lingo/lingo-gr.cpp"
+#line 3683 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 140: /* frameargs: expr tOF tMOVIE expr  */
-#line 506 "engines/director/lingo/lingo-gr.y"
+  case 142: /* frameargs: expr tOF tMOVIE expr  */
+#line 508 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `play arg of movie arg` (weird but valid)
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-3].node));
 		args->push_back(new MovieNode((yyvsp[0].node)));
 		(yyval.nodelist) = args; }
-#line 3646 "engines/director/lingo/lingo-gr.cpp"
+#line 3694 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 141: /* frameargs: tFRAME expr expr_nounarymath  */
-#line 512 "engines/director/lingo/lingo-gr.y"
+  case 143: /* frameargs: tFRAME expr expr_nounarymath  */
+#line 514 "engines/director/lingo/lingo-gr.y"
                                                         {
 		// This matches `play frame arg arg` (also weird but valid)
 		NodeList *args = new NodeList;
 		args->push_back(new FrameNode((yyvsp[-1].node)));
 		args->push_back((yyvsp[0].node));
 		(yyval.nodelist) = args; }
-#line 3657 "engines/director/lingo/lingo-gr.cpp"
+#line 3705 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 142: /* asgn: tPUT expr tINTO varorchunk '\n'  */
-#line 520 "engines/director/lingo/lingo-gr.y"
+  case 144: /* asgn: tPUT expr tINTO varorchunk '\n'  */
+#line 522 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new PutIntoNode((yyvsp[-3].node), (yyvsp[-1].node)); }
-#line 3663 "engines/director/lingo/lingo-gr.cpp"
+#line 3711 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 143: /* asgn: tPUT expr tAFTER varorchunk '\n'  */
-#line 521 "engines/director/lingo/lingo-gr.y"
+  case 145: /* asgn: tPUT expr tAFTER varorchunk '\n'  */
+#line 523 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PutAfterNode((yyvsp[-3].node), (yyvsp[-1].node)); }
-#line 3669 "engines/director/lingo/lingo-gr.cpp"
+#line 3717 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 144: /* asgn: tPUT expr tBEFORE varorchunk '\n'  */
-#line 522 "engines/director/lingo/lingo-gr.y"
+  case 146: /* asgn: tPUT expr tBEFORE varorchunk '\n'  */
+#line 524 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PutBeforeNode((yyvsp[-3].node), (yyvsp[-1].node)); }
-#line 3675 "engines/director/lingo/lingo-gr.cpp"
+#line 3723 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 145: /* asgn: tSET varorthe to expr '\n'  */
-#line 523 "engines/director/lingo/lingo-gr.y"
+  case 147: /* asgn: tSET varorthe to expr '\n'  */
+#line 525 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new SetNode((yyvsp[-3].node), (yyvsp[-1].node)); }
-#line 3681 "engines/director/lingo/lingo-gr.cpp"
+#line 3729 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 148: /* definevars: tGLOBAL idlist '\n'  */
-#line 528 "engines/director/lingo/lingo-gr.y"
+  case 150: /* definevars: tGLOBAL idlist '\n'  */
+#line 530 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new GlobalNode((yyvsp[-1].idlist)); }
-#line 3687 "engines/director/lingo/lingo-gr.cpp"
+#line 3735 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 149: /* definevars: tPROPERTY idlist '\n'  */
-#line 529 "engines/director/lingo/lingo-gr.y"
+  case 151: /* definevars: tPROPERTY idlist '\n'  */
+#line 531 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new PropertyNode((yyvsp[-1].idlist)); }
-#line 3693 "engines/director/lingo/lingo-gr.cpp"
+#line 3741 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 150: /* definevars: tINSTANCE idlist '\n'  */
-#line 530 "engines/director/lingo/lingo-gr.y"
+  case 152: /* definevars: tINSTANCE idlist '\n'  */
+#line 532 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new InstanceNode((yyvsp[-1].idlist)); }
-#line 3699 "engines/director/lingo/lingo-gr.cpp"
+#line 3747 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 151: /* ifstmt: tIF expr tTHEN stmt  */
-#line 533 "engines/director/lingo/lingo-gr.y"
+  case 153: /* ifstmt: tIF expr tTHEN stmt  */
+#line 535 "engines/director/lingo/lingo-gr.y"
                             {
 		NodeList *stmtlist = new NodeList;
 		stmtlist->push_back((yyvsp[0].node));
 		(yyval.node) = new IfStmtNode((yyvsp[-2].node), stmtlist); }
-#line 3708 "engines/director/lingo/lingo-gr.cpp"
+#line 3756 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 152: /* ifstmt: tIF expr tTHEN '\n' stmtlist_insideif endif  */
-#line 537 "engines/director/lingo/lingo-gr.y"
+  case 154: /* ifstmt: tIF expr tTHEN '\n' stmtlist_insideif endif  */
+#line 539 "engines/director/lingo/lingo-gr.y"
                                                       {
 		(yyval.node) = new IfStmtNode((yyvsp[-4].node), (yyvsp[-1].nodelist)); }
-#line 3715 "engines/director/lingo/lingo-gr.cpp"
+#line 3763 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 153: /* ifelsestmt: tIF expr tTHEN stmt tELSE stmt  */
-#line 541 "engines/director/lingo/lingo-gr.y"
+  case 155: /* ifelsestmt: tIF expr tTHEN stmt tELSE stmt  */
+#line 543 "engines/director/lingo/lingo-gr.y"
                                                          {
 		NodeList *stmtlist1 = new NodeList;
 		stmtlist1->push_back((yyvsp[-2].node));
 		NodeList *stmtlist2 = new NodeList;
 		stmtlist2->push_back((yyvsp[0].node));
 		(yyval.node) = new IfElseStmtNode((yyvsp[-4].node), stmtlist1, stmtlist2); }
-#line 3726 "engines/director/lingo/lingo-gr.cpp"
+#line 3774 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 154: /* ifelsestmt: tIF expr tTHEN stmt tELSE '\n' stmtlist_insideif endif  */
-#line 547 "engines/director/lingo/lingo-gr.y"
+  case 156: /* ifelsestmt: tIF expr tTHEN stmt tELSE '\n' stmtlist_insideif endif  */
+#line 549 "engines/director/lingo/lingo-gr.y"
                                                                                    {
 		NodeList *stmtlist1 = new NodeList;
 		stmtlist1->push_back((yyvsp[-4].node));
 		(yyval.node) = new IfElseStmtNode((yyvsp[-6].node), stmtlist1, (yyvsp[-1].nodelist)); }
-#line 3735 "engines/director/lingo/lingo-gr.cpp"
+#line 3783 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 155: /* ifelsestmt: tIF expr tTHEN '\n' stmtlist_insideif tELSE stmt  */
-#line 551 "engines/director/lingo/lingo-gr.y"
+  case 157: /* ifelsestmt: tIF expr tTHEN '\n' stmtlist_insideif tELSE stmt  */
+#line 553 "engines/director/lingo/lingo-gr.y"
                                                                              {
 		NodeList *stmtlist2 = new NodeList;
 		stmtlist2->push_back((yyvsp[0].node));
 		(yyval.node) = new IfElseStmtNode((yyvsp[-5].node), (yyvsp[-2].nodelist), stmtlist2); }
-#line 3744 "engines/director/lingo/lingo-gr.cpp"
+#line 3792 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 156: /* ifelsestmt: tIF expr tTHEN '\n' stmtlist_insideif tELSE '\n' stmtlist_insideif endif  */
-#line 555 "engines/director/lingo/lingo-gr.y"
+  case 158: /* ifelsestmt: tIF expr tTHEN '\n' stmtlist_insideif tELSE '\n' stmtlist_insideif endif  */
+#line 557 "engines/director/lingo/lingo-gr.y"
                                                                                                          {
 		(yyval.node) = new IfElseStmtNode((yyvsp[-7].node), (yyvsp[-4].nodelist), (yyvsp[-1].nodelist)); }
-#line 3751 "engines/director/lingo/lingo-gr.cpp"
+#line 3799 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 157: /* endif: %empty  */
-#line 559 "engines/director/lingo/lingo-gr.y"
+  case 159: /* endif: %empty  */
+#line 561 "engines/director/lingo/lingo-gr.y"
                         {
 		LingoCompiler *compiler = g_lingo->_compiler;
 		warning("LingoCompiler::parse: no end if at line %d col %d in %s id: %d",
@@ -3759,955 +3807,967 @@ yyreduce:
 			compiler->_assemblyContext->_id);
 
 		}
-#line 3763 "engines/director/lingo/lingo-gr.cpp"
+#line 3811 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 159: /* loop: tREPEAT tWHILE expr '\n' stmtlist tENDREPEAT '\n'  */
-#line 568 "engines/director/lingo/lingo-gr.y"
+  case 161: /* loop: tREPEAT tWHILE expr '\n' stmtlist tENDREPEAT '\n'  */
+#line 570 "engines/director/lingo/lingo-gr.y"
                                                         {
 		(yyval.node) = new RepeatWhileNode((yyvsp[-4].node), (yyvsp[-2].nodelist)); }
-#line 3770 "engines/director/lingo/lingo-gr.cpp"
+#line 3818 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 160: /* loop: tREPEAT tWITH ID tEQ expr tTO expr '\n' stmtlist tENDREPEAT '\n'  */
-#line 570 "engines/director/lingo/lingo-gr.y"
+  case 162: /* loop: tREPEAT tWITH ID tEQ expr tTO expr '\n' stmtlist tENDREPEAT '\n'  */
+#line 572 "engines/director/lingo/lingo-gr.y"
                                                                                        {
 		(yyval.node) = new RepeatWithToNode((yyvsp[-8].s), (yyvsp[-6].node), false, (yyvsp[-4].node), (yyvsp[-2].nodelist)); }
-#line 3777 "engines/director/lingo/lingo-gr.cpp"
+#line 3825 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 161: /* loop: tREPEAT tWITH ID tEQ expr tDOWN tTO expr '\n' stmtlist tENDREPEAT '\n'  */
-#line 572 "engines/director/lingo/lingo-gr.y"
+  case 163: /* loop: tREPEAT tWITH ID tEQ expr tDOWN tTO expr '\n' stmtlist tENDREPEAT '\n'  */
+#line 574 "engines/director/lingo/lingo-gr.y"
                                                                                              {
 		(yyval.node) = new RepeatWithToNode((yyvsp[-9].s), (yyvsp[-7].node), true, (yyvsp[-4].node), (yyvsp[-2].nodelist)); }
-#line 3784 "engines/director/lingo/lingo-gr.cpp"
+#line 3832 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 162: /* loop: tREPEAT tWITH ID tIN expr '\n' stmtlist tENDREPEAT '\n'  */
-#line 574 "engines/director/lingo/lingo-gr.y"
+  case 164: /* loop: tREPEAT tWITH ID tIN expr '\n' stmtlist tENDREPEAT '\n'  */
+#line 576 "engines/director/lingo/lingo-gr.y"
                                                                   {
 		(yyval.node) = new RepeatWithInNode((yyvsp[-6].s), (yyvsp[-4].node), (yyvsp[-2].nodelist)); }
-#line 3791 "engines/director/lingo/lingo-gr.cpp"
+#line 3839 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 163: /* tell: tTELL expr tTO stmtoneliner  */
-#line 578 "engines/director/lingo/lingo-gr.y"
+  case 165: /* tell: tTELL expr tTO stmtoneliner  */
+#line 580 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		NodeList *stmtlist = new NodeList;
 		stmtlist->push_back((yyvsp[0].node));
 		(yyval.node) = new TellNode((yyvsp[-2].node), stmtlist); }
-#line 3800 "engines/director/lingo/lingo-gr.cpp"
+#line 3848 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 164: /* tell: tTELL expr '\n' stmtlist tENDTELL '\n'  */
-#line 582 "engines/director/lingo/lingo-gr.y"
+  case 166: /* tell: tTELL expr '\n' stmtlist tENDTELL '\n'  */
+#line 584 "engines/director/lingo/lingo-gr.y"
                                                         {
 		(yyval.node) = new TellNode((yyvsp[-4].node), (yyvsp[-2].nodelist)); }
-#line 3807 "engines/director/lingo/lingo-gr.cpp"
+#line 3855 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 165: /* when: tWHEN '\n'  */
-#line 586 "engines/director/lingo/lingo-gr.y"
+  case 167: /* when: tWHEN '\n'  */
+#line 588 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new WhenNode((yyvsp[-1].w).eventName, (yyvsp[-1].w).stmt); }
-#line 3813 "engines/director/lingo/lingo-gr.cpp"
+#line 3861 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 166: /* stmtlist: %empty  */
-#line 588 "engines/director/lingo/lingo-gr.y"
+  case 168: /* stmtlist: %empty  */
+#line 590 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.nodelist) = new NodeList; }
-#line 3819 "engines/director/lingo/lingo-gr.cpp"
+#line 3867 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 168: /* nonemptystmtlist: stmtlistline  */
-#line 593 "engines/director/lingo/lingo-gr.y"
+  case 170: /* nonemptystmtlist: stmtlistline  */
+#line 595 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		NodeList *list = new NodeList;
 		if ((yyvsp[0].node)) {
 			list->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = list; }
-#line 3830 "engines/director/lingo/lingo-gr.cpp"
+#line 3878 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 169: /* nonemptystmtlist: nonemptystmtlist stmtlistline  */
-#line 599 "engines/director/lingo/lingo-gr.y"
+  case 171: /* nonemptystmtlist: nonemptystmtlist stmtlistline  */
+#line 601 "engines/director/lingo/lingo-gr.y"
                                                         {
 		if ((yyvsp[0].node)) {
 			(yyvsp[-1].nodelist)->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 3840 "engines/director/lingo/lingo-gr.cpp"
+#line 3888 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 170: /* stmtlistline: '\n'  */
-#line 606 "engines/director/lingo/lingo-gr.y"
+  case 172: /* stmtlistline: '\n'  */
+#line 608 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = nullptr; }
-#line 3846 "engines/director/lingo/lingo-gr.cpp"
+#line 3894 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 172: /* stmtlist_insideif: %empty  */
-#line 610 "engines/director/lingo/lingo-gr.y"
+  case 174: /* stmtlist_insideif: %empty  */
+#line 612 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.nodelist) = new NodeList; }
-#line 3852 "engines/director/lingo/lingo-gr.cpp"
+#line 3900 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 174: /* nonemptystmtlist_insideif: stmtlistline_insideif  */
-#line 615 "engines/director/lingo/lingo-gr.y"
+  case 176: /* nonemptystmtlist_insideif: stmtlistline_insideif  */
+#line 617 "engines/director/lingo/lingo-gr.y"
                                                 {
 		NodeList *list = new NodeList;
 		if ((yyvsp[0].node)) {
 			list->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = list; }
-#line 3863 "engines/director/lingo/lingo-gr.cpp"
+#line 3911 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 175: /* nonemptystmtlist_insideif: nonemptystmtlist_insideif stmtlistline_insideif  */
-#line 621 "engines/director/lingo/lingo-gr.y"
+  case 177: /* nonemptystmtlist_insideif: nonemptystmtlist_insideif stmtlistline_insideif  */
+#line 623 "engines/director/lingo/lingo-gr.y"
                                                                         {
 		if ((yyvsp[0].node)) {
 			(yyvsp[-1].nodelist)->push_back((yyvsp[0].node));
 		}
 		(yyval.nodelist) = (yyvsp[-1].nodelist); }
-#line 3873 "engines/director/lingo/lingo-gr.cpp"
+#line 3921 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 176: /* stmtlistline_insideif: '\n'  */
-#line 628 "engines/director/lingo/lingo-gr.y"
+  case 178: /* stmtlistline_insideif: '\n'  */
+#line 630 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = nullptr; }
-#line 3879 "engines/director/lingo/lingo-gr.cpp"
+#line 3927 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 178: /* simpleexpr_nounarymath: tINT  */
-#line 635 "engines/director/lingo/lingo-gr.y"
+  case 180: /* simpleexpr_nounarymath: tINT  */
+#line 637 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new IntNode((yyvsp[0].i)); }
-#line 3885 "engines/director/lingo/lingo-gr.cpp"
+#line 3933 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 179: /* simpleexpr_nounarymath: tFLOAT  */
-#line 636 "engines/director/lingo/lingo-gr.y"
+  case 181: /* simpleexpr_nounarymath: tFLOAT  */
+#line 638 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new FloatNode((yyvsp[0].f)); }
-#line 3891 "engines/director/lingo/lingo-gr.cpp"
+#line 3939 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 180: /* simpleexpr_nounarymath: tSYMBOL  */
-#line 637 "engines/director/lingo/lingo-gr.y"
+  case 182: /* simpleexpr_nounarymath: tSYMBOL  */
+#line 639 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new SymbolNode((yyvsp[0].s)); }
-#line 3897 "engines/director/lingo/lingo-gr.cpp"
+#line 3945 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 181: /* simpleexpr_nounarymath: tSTRING  */
-#line 638 "engines/director/lingo/lingo-gr.y"
+  case 183: /* simpleexpr_nounarymath: tSTRING  */
+#line 640 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new StringNode((yyvsp[0].s)); }
-#line 3903 "engines/director/lingo/lingo-gr.cpp"
+#line 3951 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 182: /* simpleexpr_nounarymath: tNOT simpleexpr  */
-#line 639 "engines/director/lingo/lingo-gr.y"
+  case 184: /* simpleexpr_nounarymath: tNOT simpleexpr  */
+#line 641 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new UnaryOpNode(LC::c_not, (yyvsp[0].node)); }
-#line 3909 "engines/director/lingo/lingo-gr.cpp"
+#line 3957 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 183: /* simpleexpr_nounarymath: ID '(' ')'  */
-#line 640 "engines/director/lingo/lingo-gr.y"
+  case 185: /* simpleexpr_nounarymath: ID '(' ')'  */
+#line 642 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new FuncNode((yyvsp[-2].s), new NodeList); }
-#line 3915 "engines/director/lingo/lingo-gr.cpp"
+#line 3963 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 184: /* simpleexpr_nounarymath: ID '(' nonemptyexprlist trailingcomma ')'  */
-#line 641 "engines/director/lingo/lingo-gr.y"
+  case 186: /* simpleexpr_nounarymath: ID '(' nonemptyexprlist trailingcomma ')'  */
+#line 643 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new FuncNode((yyvsp[-4].s), (yyvsp[-2].nodelist)); }
-#line 3921 "engines/director/lingo/lingo-gr.cpp"
+#line 3969 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 185: /* simpleexpr_nounarymath: ID '(' var expr_nounarymath trailingcomma ')'  */
-#line 642 "engines/director/lingo/lingo-gr.y"
+  case 187: /* simpleexpr_nounarymath: ID '(' var expr_nounarymath trailingcomma ')'  */
+#line 644 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `obj(method arg)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-3].node));
 		args->push_back((yyvsp[-2].node));
 		(yyval.node) = new FuncNode((yyvsp[-5].s), args); }
-#line 3932 "engines/director/lingo/lingo-gr.cpp"
+#line 3980 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 186: /* simpleexpr_nounarymath: ID '(' var expr_nounarymath ',' nonemptyexprlist trailingcomma ')'  */
-#line 648 "engines/director/lingo/lingo-gr.y"
+  case 188: /* simpleexpr_nounarymath: ID '(' var expr_nounarymath ',' nonemptyexprlist trailingcomma ')'  */
+#line 650 "engines/director/lingo/lingo-gr.y"
                                                                                                 {
 		// This matches `obj(method arg, ...)`
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-4].node));
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-5].node));
 		(yyval.node) = new FuncNode((yyvsp[-7].s), (yyvsp[-2].nodelist)); }
-#line 3942 "engines/director/lingo/lingo-gr.cpp"
+#line 3990 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 187: /* simpleexpr_nounarymath: '(' expr ')'  */
-#line 653 "engines/director/lingo/lingo-gr.y"
+  case 189: /* simpleexpr_nounarymath: '(' expr ')'  */
+#line 655 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = (yyvsp[-1].node); }
-#line 3948 "engines/director/lingo/lingo-gr.cpp"
+#line 3996 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 193: /* var: ID  */
-#line 661 "engines/director/lingo/lingo-gr.y"
+  case 195: /* var: ID  */
+#line 663 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new VarNode((yyvsp[0].s)); }
-#line 3954 "engines/director/lingo/lingo-gr.cpp"
+#line 4002 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 198: /* chunk: tFIELD refargs  */
-#line 671 "engines/director/lingo/lingo-gr.y"
+  case 200: /* chunk: tFIELD refargs  */
+#line 673 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.node) = new FuncNode(new Common::String("field"), (yyvsp[0].nodelist)); }
-#line 3960 "engines/director/lingo/lingo-gr.cpp"
+#line 4008 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 199: /* chunk: tCAST refargs  */
-#line 672 "engines/director/lingo/lingo-gr.y"
+  case 201: /* chunk: tCAST refargs  */
+#line 674 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new FuncNode(new Common::String("cast"), (yyvsp[0].nodelist)); }
-#line 3966 "engines/director/lingo/lingo-gr.cpp"
+#line 4014 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 200: /* chunk: tCHAR expr tOF simpleexpr  */
-#line 673 "engines/director/lingo/lingo-gr.y"
+  case 202: /* chunk: tMEMBER refargs  */
+#line 675 "engines/director/lingo/lingo-gr.y"
+                                        { (yyval.node) = new FuncNode(new Common::String("member"), (yyvsp[0].nodelist)); }
+#line 4020 "engines/director/lingo/lingo-gr.cpp"
+    break;
+
+  case 203: /* chunk: tCASTLIB refargs  */
+#line 676 "engines/director/lingo/lingo-gr.y"
+                                        { (yyval.node) = new FuncNode(new Common::String("castLib"), (yyvsp[0].nodelist)); }
+#line 4026 "engines/director/lingo/lingo-gr.cpp"
+    break;
+
+  case 204: /* chunk: tCHAR expr tOF simpleexpr  */
+#line 677 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkChar, (yyvsp[-2].node), nullptr, (yyvsp[0].node)); }
-#line 3973 "engines/director/lingo/lingo-gr.cpp"
+#line 4033 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 201: /* chunk: tCHAR expr tTO expr tOF simpleexpr  */
-#line 675 "engines/director/lingo/lingo-gr.y"
+  case 205: /* chunk: tCHAR expr tTO expr tOF simpleexpr  */
+#line 679 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkChar, (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 3980 "engines/director/lingo/lingo-gr.cpp"
+#line 4040 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 202: /* chunk: tWORD expr tOF simpleexpr  */
-#line 677 "engines/director/lingo/lingo-gr.y"
+  case 206: /* chunk: tWORD expr tOF simpleexpr  */
+#line 681 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkWord, (yyvsp[-2].node), nullptr, (yyvsp[0].node)); }
-#line 3987 "engines/director/lingo/lingo-gr.cpp"
+#line 4047 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 203: /* chunk: tWORD expr tTO expr tOF simpleexpr  */
-#line 679 "engines/director/lingo/lingo-gr.y"
+  case 207: /* chunk: tWORD expr tTO expr tOF simpleexpr  */
+#line 683 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkWord, (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 3994 "engines/director/lingo/lingo-gr.cpp"
+#line 4054 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 204: /* chunk: tITEM expr tOF simpleexpr  */
-#line 681 "engines/director/lingo/lingo-gr.y"
+  case 208: /* chunk: tITEM expr tOF simpleexpr  */
+#line 685 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkItem, (yyvsp[-2].node), nullptr, (yyvsp[0].node)); }
-#line 4001 "engines/director/lingo/lingo-gr.cpp"
+#line 4061 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 205: /* chunk: tITEM expr tTO expr tOF simpleexpr  */
-#line 683 "engines/director/lingo/lingo-gr.y"
+  case 209: /* chunk: tITEM expr tTO expr tOF simpleexpr  */
+#line 687 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkItem, (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4008 "engines/director/lingo/lingo-gr.cpp"
+#line 4068 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 206: /* chunk: tLINE expr tOF simpleexpr  */
-#line 685 "engines/director/lingo/lingo-gr.y"
+  case 210: /* chunk: tLINE expr tOF simpleexpr  */
+#line 689 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkLine, (yyvsp[-2].node), nullptr, (yyvsp[0].node)); }
-#line 4015 "engines/director/lingo/lingo-gr.cpp"
+#line 4075 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 207: /* chunk: tLINE expr tTO expr tOF simpleexpr  */
-#line 687 "engines/director/lingo/lingo-gr.y"
+  case 211: /* chunk: tLINE expr tTO expr tOF simpleexpr  */
+#line 691 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		(yyval.node) = new ChunkExprNode(kChunkLine, (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4022 "engines/director/lingo/lingo-gr.cpp"
+#line 4082 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 208: /* chunk: tTHE tLAST chunktype inof simpleexpr  */
-#line 689 "engines/director/lingo/lingo-gr.y"
+  case 212: /* chunk: tTHE tLAST chunktype inof simpleexpr  */
+#line 693 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new TheLastNode((yyvsp[-2].chunktype), (yyvsp[0].node)); }
-#line 4028 "engines/director/lingo/lingo-gr.cpp"
+#line 4088 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 209: /* chunktype: tCHAR  */
-#line 692 "engines/director/lingo/lingo-gr.y"
+  case 213: /* chunktype: tCHAR  */
+#line 696 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.chunktype) = kChunkChar; }
-#line 4034 "engines/director/lingo/lingo-gr.cpp"
+#line 4094 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 210: /* chunktype: tWORD  */
-#line 693 "engines/director/lingo/lingo-gr.y"
+  case 214: /* chunktype: tWORD  */
+#line 697 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.chunktype) = kChunkWord; }
-#line 4040 "engines/director/lingo/lingo-gr.cpp"
+#line 4100 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 211: /* chunktype: tITEM  */
-#line 694 "engines/director/lingo/lingo-gr.y"
+  case 215: /* chunktype: tITEM  */
+#line 698 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.chunktype) = kChunkItem; }
-#line 4046 "engines/director/lingo/lingo-gr.cpp"
+#line 4106 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 212: /* chunktype: tLINE  */
-#line 695 "engines/director/lingo/lingo-gr.y"
+  case 216: /* chunktype: tLINE  */
+#line 699 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.chunktype) = kChunkLine; }
-#line 4052 "engines/director/lingo/lingo-gr.cpp"
+#line 4112 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 213: /* object: tSCRIPT refargs  */
-#line 698 "engines/director/lingo/lingo-gr.y"
+  case 217: /* object: tSCRIPT refargs  */
+#line 702 "engines/director/lingo/lingo-gr.y"
                                 { (yyval.node) = new FuncNode(new Common::String("script"), (yyvsp[0].nodelist)); }
-#line 4058 "engines/director/lingo/lingo-gr.cpp"
+#line 4118 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 214: /* object: tWINDOW refargs  */
-#line 699 "engines/director/lingo/lingo-gr.y"
+  case 218: /* object: tWINDOW refargs  */
+#line 703 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new FuncNode(new Common::String("window"), (yyvsp[0].nodelist)); }
-#line 4064 "engines/director/lingo/lingo-gr.cpp"
+#line 4124 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 215: /* refargs: simpleexpr  */
-#line 702 "engines/director/lingo/lingo-gr.y"
+  case 219: /* refargs: simpleexpr  */
+#line 706 "engines/director/lingo/lingo-gr.y"
                                                                                 {
 		// This matches `ref arg` and `ref(arg)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[0].node));
 		(yyval.nodelist) = args; }
-#line 4074 "engines/director/lingo/lingo-gr.cpp"
+#line 4134 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 216: /* refargs: '(' ')'  */
-#line 707 "engines/director/lingo/lingo-gr.y"
+  case 220: /* refargs: '(' ')'  */
+#line 711 "engines/director/lingo/lingo-gr.y"
                                                                                         {
 		// This matches `ref()`
 		(yyval.nodelist) = new NodeList; }
-#line 4082 "engines/director/lingo/lingo-gr.cpp"
+#line 4142 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 217: /* refargs: '(' expr ',' ')'  */
-#line 710 "engines/director/lingo/lingo-gr.y"
+  case 221: /* refargs: '(' expr ',' ')'  */
+#line 714 "engines/director/lingo/lingo-gr.y"
                            {
 		// This matches `ref(arg,)`
 		NodeList *args = new NodeList;
 		args->push_back((yyvsp[-2].node));
 		(yyval.nodelist) = args; }
-#line 4092 "engines/director/lingo/lingo-gr.cpp"
+#line 4152 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 218: /* refargs: '(' expr ',' nonemptyexprlist trailingcomma ')'  */
-#line 715 "engines/director/lingo/lingo-gr.y"
+  case 222: /* refargs: '(' expr ',' nonemptyexprlist trailingcomma ')'  */
+#line 719 "engines/director/lingo/lingo-gr.y"
                                                                 {
 		// This matches `ref(arg, ...)`
 		(yyvsp[-2].nodelist)->insert_at(0, (yyvsp[-4].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 4101 "engines/director/lingo/lingo-gr.cpp"
+#line 4161 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 219: /* the: tTHE ID  */
-#line 721 "engines/director/lingo/lingo-gr.y"
+  case 223: /* the: tTHE ID  */
+#line 725 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheNode((yyvsp[0].s)); }
-#line 4107 "engines/director/lingo/lingo-gr.cpp"
+#line 4167 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 220: /* the: tTHE ID tOF theobj  */
-#line 722 "engines/director/lingo/lingo-gr.y"
+  case 224: /* the: tTHE ID tOF theobj  */
+#line 726 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheOfNode((yyvsp[-2].s), (yyvsp[0].node)); }
-#line 4113 "engines/director/lingo/lingo-gr.cpp"
+#line 4173 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 221: /* the: tTHE tNUMBER tOF theobj  */
-#line 723 "engines/director/lingo/lingo-gr.y"
+  case 225: /* the: tTHE tNUMBER tOF theobj  */
+#line 727 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheOfNode(new Common::String("number"), (yyvsp[0].node)); }
-#line 4119 "engines/director/lingo/lingo-gr.cpp"
+#line 4179 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 226: /* theobj: tMENUITEM simpleexpr tOF tMENU simpleexpr  */
-#line 730 "engines/director/lingo/lingo-gr.y"
+  case 230: /* theobj: tMENUITEM simpleexpr tOF tMENU simpleexpr  */
+#line 734 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new MenuItemNode((yyvsp[-3].node), (yyvsp[0].node)); }
-#line 4125 "engines/director/lingo/lingo-gr.cpp"
+#line 4185 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 227: /* theobj: tSOUND simpleexpr  */
-#line 731 "engines/director/lingo/lingo-gr.y"
+  case 231: /* theobj: tSOUND simpleexpr  */
+#line 735 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new SoundNode((yyvsp[0].node)); }
-#line 4131 "engines/director/lingo/lingo-gr.cpp"
+#line 4191 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 228: /* theobj: tSPRITE simpleexpr  */
-#line 732 "engines/director/lingo/lingo-gr.y"
+  case 232: /* theobj: tSPRITE simpleexpr  */
+#line 736 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new SpriteNode((yyvsp[0].node)); }
-#line 4137 "engines/director/lingo/lingo-gr.cpp"
+#line 4197 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 229: /* menu: tMENU simpleexpr  */
-#line 735 "engines/director/lingo/lingo-gr.y"
+  case 233: /* menu: tMENU simpleexpr  */
+#line 739 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new MenuNode((yyvsp[0].node)); }
-#line 4143 "engines/director/lingo/lingo-gr.cpp"
+#line 4203 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 230: /* thedatetime: tTHE tABBREVIATED tDATE  */
-#line 737 "engines/director/lingo/lingo-gr.y"
+  case 234: /* thedatetime: tTHE tABBREVIATED tDATE  */
+#line 741 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheDate); }
-#line 4149 "engines/director/lingo/lingo-gr.cpp"
+#line 4209 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 231: /* thedatetime: tTHE tABBREVIATED tTIME  */
-#line 738 "engines/director/lingo/lingo-gr.y"
+  case 235: /* thedatetime: tTHE tABBREVIATED tTIME  */
+#line 742 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheTime); }
-#line 4155 "engines/director/lingo/lingo-gr.cpp"
+#line 4215 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 232: /* thedatetime: tTHE tABBREV tDATE  */
-#line 739 "engines/director/lingo/lingo-gr.y"
+  case 236: /* thedatetime: tTHE tABBREV tDATE  */
+#line 743 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheDate); }
-#line 4161 "engines/director/lingo/lingo-gr.cpp"
+#line 4221 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 233: /* thedatetime: tTHE tABBREV tTIME  */
-#line 740 "engines/director/lingo/lingo-gr.y"
+  case 237: /* thedatetime: tTHE tABBREV tTIME  */
+#line 744 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheTime); }
-#line 4167 "engines/director/lingo/lingo-gr.cpp"
+#line 4227 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 234: /* thedatetime: tTHE tABBR tDATE  */
-#line 741 "engines/director/lingo/lingo-gr.y"
+  case 238: /* thedatetime: tTHE tABBR tDATE  */
+#line 745 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheDate); }
-#line 4173 "engines/director/lingo/lingo-gr.cpp"
+#line 4233 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 235: /* thedatetime: tTHE tABBR tTIME  */
-#line 742 "engines/director/lingo/lingo-gr.y"
+  case 239: /* thedatetime: tTHE tABBR tTIME  */
+#line 746 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheAbbr, kTheTime); }
-#line 4179 "engines/director/lingo/lingo-gr.cpp"
+#line 4239 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 236: /* thedatetime: tTHE tLONG tDATE  */
-#line 743 "engines/director/lingo/lingo-gr.y"
+  case 240: /* thedatetime: tTHE tLONG tDATE  */
+#line 747 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheLong, kTheDate); }
-#line 4185 "engines/director/lingo/lingo-gr.cpp"
+#line 4245 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 237: /* thedatetime: tTHE tLONG tTIME  */
-#line 744 "engines/director/lingo/lingo-gr.y"
+  case 241: /* thedatetime: tTHE tLONG tTIME  */
+#line 748 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheLong, kTheTime); }
-#line 4191 "engines/director/lingo/lingo-gr.cpp"
+#line 4251 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 238: /* thedatetime: tTHE tSHORT tDATE  */
-#line 745 "engines/director/lingo/lingo-gr.y"
+  case 242: /* thedatetime: tTHE tSHORT tDATE  */
+#line 749 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheShort, kTheDate); }
-#line 4197 "engines/director/lingo/lingo-gr.cpp"
+#line 4257 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 239: /* thedatetime: tTHE tSHORT tTIME  */
-#line 746 "engines/director/lingo/lingo-gr.y"
+  case 243: /* thedatetime: tTHE tSHORT tTIME  */
+#line 750 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheDateTimeNode(kTheShort, kTheTime); }
-#line 4203 "engines/director/lingo/lingo-gr.cpp"
+#line 4263 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 240: /* thenumberof: tTHE tNUMBER tOF tCHARS inof simpleexpr  */
-#line 750 "engines/director/lingo/lingo-gr.y"
+  case 244: /* thenumberof: tTHE tNUMBER tOF tCHARS inof simpleexpr  */
+#line 754 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfChars, (yyvsp[0].node)); }
-#line 4209 "engines/director/lingo/lingo-gr.cpp"
+#line 4269 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 241: /* thenumberof: tTHE tNUMBER tOF tWORDS inof simpleexpr  */
-#line 751 "engines/director/lingo/lingo-gr.y"
+  case 245: /* thenumberof: tTHE tNUMBER tOF tWORDS inof simpleexpr  */
+#line 755 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfWords, (yyvsp[0].node)); }
-#line 4215 "engines/director/lingo/lingo-gr.cpp"
+#line 4275 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 242: /* thenumberof: tTHE tNUMBER tOF tITEMS inof simpleexpr  */
-#line 752 "engines/director/lingo/lingo-gr.y"
+  case 246: /* thenumberof: tTHE tNUMBER tOF tITEMS inof simpleexpr  */
+#line 756 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfItems, (yyvsp[0].node)); }
-#line 4221 "engines/director/lingo/lingo-gr.cpp"
+#line 4281 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 243: /* thenumberof: tTHE tNUMBER tOF tLINES inof simpleexpr  */
-#line 753 "engines/director/lingo/lingo-gr.y"
+  case 247: /* thenumberof: tTHE tNUMBER tOF tLINES inof simpleexpr  */
+#line 757 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfLines, (yyvsp[0].node)); }
-#line 4227 "engines/director/lingo/lingo-gr.cpp"
+#line 4287 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 244: /* thenumberof: tTHE tNUMBER tOF tMENUITEMS inof menu  */
-#line 754 "engines/director/lingo/lingo-gr.y"
+  case 248: /* thenumberof: tTHE tNUMBER tOF tMENUITEMS inof menu  */
+#line 758 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfMenuItems, (yyvsp[0].node)); }
-#line 4233 "engines/director/lingo/lingo-gr.cpp"
+#line 4293 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 245: /* thenumberof: tTHE tNUMBER tOF tMENUS  */
-#line 755 "engines/director/lingo/lingo-gr.y"
+  case 249: /* thenumberof: tTHE tNUMBER tOF tMENUS  */
+#line 759 "engines/director/lingo/lingo-gr.y"
                                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfMenus, nullptr); }
-#line 4239 "engines/director/lingo/lingo-gr.cpp"
+#line 4299 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 246: /* thenumberof: tTHE tNUMBER tOF tXTRAS  */
-#line 756 "engines/director/lingo/lingo-gr.y"
+  case 250: /* thenumberof: tTHE tNUMBER tOF tXTRAS  */
+#line 760 "engines/director/lingo/lingo-gr.y"
                                                                         { (yyval.node) = new TheNumberOfNode(kNumberOfXtras, nullptr); }
-#line 4245 "engines/director/lingo/lingo-gr.cpp"
+#line 4305 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 247: /* thenumberof: tTHE tNUMBER tOF tCASTLIBS  */
-#line 757 "engines/director/lingo/lingo-gr.y"
+  case 251: /* thenumberof: tTHE tNUMBER tOF tCASTLIBS  */
+#line 761 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new TheNumberOfNode(kNumberOfCastlibs, nullptr); }
-#line 4251 "engines/director/lingo/lingo-gr.cpp"
+#line 4311 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 250: /* writablethe: tTHE ID  */
-#line 762 "engines/director/lingo/lingo-gr.y"
+  case 254: /* writablethe: tTHE ID  */
+#line 766 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new TheNode((yyvsp[0].s)); }
-#line 4257 "engines/director/lingo/lingo-gr.cpp"
+#line 4317 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 251: /* writablethe: tTHE ID tOF writabletheobj  */
-#line 763 "engines/director/lingo/lingo-gr.y"
+  case 255: /* writablethe: tTHE ID tOF writabletheobj  */
+#line 767 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new TheOfNode((yyvsp[-2].s), (yyvsp[0].node)); }
-#line 4263 "engines/director/lingo/lingo-gr.cpp"
+#line 4323 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 253: /* writabletheobj: tMENU expr_noeq  */
-#line 767 "engines/director/lingo/lingo-gr.y"
+  case 257: /* writabletheobj: tMENU expr_noeq  */
+#line 771 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new MenuNode((yyvsp[0].node)); }
-#line 4269 "engines/director/lingo/lingo-gr.cpp"
+#line 4329 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 254: /* writabletheobj: tMENUITEM expr_noeq tOF tMENU expr_noeq  */
-#line 768 "engines/director/lingo/lingo-gr.y"
+  case 258: /* writabletheobj: tMENUITEM expr_noeq tOF tMENU expr_noeq  */
+#line 772 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new MenuItemNode((yyvsp[-3].node), (yyvsp[0].node)); }
-#line 4275 "engines/director/lingo/lingo-gr.cpp"
+#line 4335 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 255: /* writabletheobj: tSOUND expr_noeq  */
-#line 769 "engines/director/lingo/lingo-gr.y"
+  case 259: /* writabletheobj: tSOUND expr_noeq  */
+#line 773 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new SoundNode((yyvsp[0].node)); }
-#line 4281 "engines/director/lingo/lingo-gr.cpp"
+#line 4341 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 256: /* writabletheobj: tSPRITE expr_noeq  */
-#line 770 "engines/director/lingo/lingo-gr.y"
+  case 260: /* writabletheobj: tSPRITE expr_noeq  */
+#line 774 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new SpriteNode((yyvsp[0].node)); }
-#line 4287 "engines/director/lingo/lingo-gr.cpp"
+#line 4347 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 257: /* list: '[' exprlist ']'  */
-#line 773 "engines/director/lingo/lingo-gr.y"
+  case 261: /* list: '[' exprlist ']'  */
+#line 777 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new ListNode((yyvsp[-1].nodelist)); }
-#line 4293 "engines/director/lingo/lingo-gr.cpp"
+#line 4353 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 258: /* list: '[' ':' ']'  */
-#line 774 "engines/director/lingo/lingo-gr.y"
+  case 262: /* list: '[' ':' ']'  */
+#line 778 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PropListNode(new NodeList); }
-#line 4299 "engines/director/lingo/lingo-gr.cpp"
+#line 4359 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 259: /* list: '[' proplist ']'  */
-#line 775 "engines/director/lingo/lingo-gr.y"
+  case 263: /* list: '[' proplist ']'  */
+#line 779 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PropListNode((yyvsp[-1].nodelist)); }
-#line 4305 "engines/director/lingo/lingo-gr.cpp"
+#line 4365 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 260: /* proplist: proppair  */
-#line 781 "engines/director/lingo/lingo-gr.y"
+  case 264: /* proplist: proppair  */
+#line 785 "engines/director/lingo/lingo-gr.y"
                                                         {
 		NodeList *list = new NodeList;
 		list->push_back((yyvsp[0].node));
 		(yyval.nodelist) = list; }
-#line 4314 "engines/director/lingo/lingo-gr.cpp"
+#line 4374 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 261: /* proplist: proplist ',' proppair  */
-#line 785 "engines/director/lingo/lingo-gr.y"
+  case 265: /* proplist: proplist ',' proppair  */
+#line 789 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyvsp[-2].nodelist)->push_back((yyvsp[0].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 4322 "engines/director/lingo/lingo-gr.cpp"
+#line 4382 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 262: /* proplist: proplist ',' expr  */
-#line 788 "engines/director/lingo/lingo-gr.y"
+  case 266: /* proplist: proplist ',' expr  */
+#line 792 "engines/director/lingo/lingo-gr.y"
                                         {
 		(yyvsp[-2].nodelist)->push_back((yyvsp[0].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 4330 "engines/director/lingo/lingo-gr.cpp"
+#line 4390 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 263: /* proppair: tSYMBOL ':' expr  */
-#line 793 "engines/director/lingo/lingo-gr.y"
+  case 267: /* proppair: tSYMBOL ':' expr  */
+#line 797 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new PropPairNode(new SymbolNode((yyvsp[-2].s)), (yyvsp[0].node)); }
-#line 4336 "engines/director/lingo/lingo-gr.cpp"
+#line 4396 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 264: /* proppair: ID ':' expr  */
-#line 794 "engines/director/lingo/lingo-gr.y"
+  case 268: /* proppair: ID ':' expr  */
+#line 798 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PropPairNode(new SymbolNode((yyvsp[-2].s)), (yyvsp[0].node)); }
-#line 4342 "engines/director/lingo/lingo-gr.cpp"
+#line 4402 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 265: /* proppair: tSTRING ':' expr  */
-#line 795 "engines/director/lingo/lingo-gr.y"
+  case 269: /* proppair: tSTRING ':' expr  */
+#line 799 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new PropPairNode(new StringNode((yyvsp[-2].s)), (yyvsp[0].node)); }
-#line 4348 "engines/director/lingo/lingo-gr.cpp"
+#line 4408 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 266: /* proppair: tINT ':' expr  */
-#line 796 "engines/director/lingo/lingo-gr.y"
+  case 270: /* proppair: tINT ':' expr  */
+#line 800 "engines/director/lingo/lingo-gr.y"
                                     { (yyval.node) = new PropPairNode(new IntNode((yyvsp[-2].i)), (yyvsp[0].node)); }
-#line 4354 "engines/director/lingo/lingo-gr.cpp"
+#line 4414 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 267: /* proppair: tFLOAT ':' expr  */
-#line 797 "engines/director/lingo/lingo-gr.y"
+  case 271: /* proppair: tFLOAT ':' expr  */
+#line 801 "engines/director/lingo/lingo-gr.y"
                                     { (yyval.node) = new PropPairNode(new FloatNode((yyvsp[-2].f)), (yyvsp[0].node)); }
-#line 4360 "engines/director/lingo/lingo-gr.cpp"
+#line 4420 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 268: /* unarymath: '+' simpleexpr  */
-#line 800 "engines/director/lingo/lingo-gr.y"
+  case 272: /* unarymath: '+' simpleexpr  */
+#line 804 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = (yyvsp[0].node); }
-#line 4366 "engines/director/lingo/lingo-gr.cpp"
+#line 4426 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 269: /* unarymath: '-' simpleexpr  */
-#line 801 "engines/director/lingo/lingo-gr.y"
+  case 273: /* unarymath: '-' simpleexpr  */
+#line 805 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.node) = new UnaryOpNode(LC::c_negate, (yyvsp[0].node)); }
-#line 4372 "engines/director/lingo/lingo-gr.cpp"
+#line 4432 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 274: /* expr: expr '+' expr  */
-#line 811 "engines/director/lingo/lingo-gr.y"
+  case 278: /* expr: expr '+' expr  */
+#line 815 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_add, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4378 "engines/director/lingo/lingo-gr.cpp"
+#line 4438 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 275: /* expr: expr '-' expr  */
-#line 812 "engines/director/lingo/lingo-gr.y"
+  case 279: /* expr: expr '-' expr  */
+#line 816 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_sub, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4384 "engines/director/lingo/lingo-gr.cpp"
+#line 4444 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 276: /* expr: expr '*' expr  */
-#line 813 "engines/director/lingo/lingo-gr.y"
+  case 280: /* expr: expr '*' expr  */
+#line 817 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_mul, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4390 "engines/director/lingo/lingo-gr.cpp"
+#line 4450 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 277: /* expr: expr '/' expr  */
-#line 814 "engines/director/lingo/lingo-gr.y"
+  case 281: /* expr: expr '/' expr  */
+#line 818 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_div, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4396 "engines/director/lingo/lingo-gr.cpp"
+#line 4456 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 278: /* expr: expr tMOD expr  */
-#line 815 "engines/director/lingo/lingo-gr.y"
+  case 282: /* expr: expr tMOD expr  */
+#line 819 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_mod, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4402 "engines/director/lingo/lingo-gr.cpp"
+#line 4462 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 279: /* expr: expr '>' expr  */
-#line 816 "engines/director/lingo/lingo-gr.y"
+  case 283: /* expr: expr '>' expr  */
+#line 820 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_gt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4408 "engines/director/lingo/lingo-gr.cpp"
+#line 4468 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 280: /* expr: expr '<' expr  */
-#line 817 "engines/director/lingo/lingo-gr.y"
+  case 284: /* expr: expr '<' expr  */
+#line 821 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_lt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4414 "engines/director/lingo/lingo-gr.cpp"
+#line 4474 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 281: /* expr: expr tEQ expr  */
-#line 818 "engines/director/lingo/lingo-gr.y"
+  case 285: /* expr: expr tEQ expr  */
+#line 822 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_eq, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4420 "engines/director/lingo/lingo-gr.cpp"
+#line 4480 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 282: /* expr: expr tNEQ expr  */
-#line 819 "engines/director/lingo/lingo-gr.y"
+  case 286: /* expr: expr tNEQ expr  */
+#line 823 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_neq, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4426 "engines/director/lingo/lingo-gr.cpp"
+#line 4486 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 283: /* expr: expr tGE expr  */
-#line 820 "engines/director/lingo/lingo-gr.y"
+  case 287: /* expr: expr tGE expr  */
+#line 824 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_ge, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4432 "engines/director/lingo/lingo-gr.cpp"
+#line 4492 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 284: /* expr: expr tLE expr  */
-#line 821 "engines/director/lingo/lingo-gr.y"
+  case 288: /* expr: expr tLE expr  */
+#line 825 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_le, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4438 "engines/director/lingo/lingo-gr.cpp"
+#line 4498 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 285: /* expr: expr tAND expr  */
-#line 822 "engines/director/lingo/lingo-gr.y"
+  case 289: /* expr: expr tAND expr  */
+#line 826 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_and, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4444 "engines/director/lingo/lingo-gr.cpp"
+#line 4504 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 286: /* expr: expr tOR expr  */
-#line 823 "engines/director/lingo/lingo-gr.y"
+  case 290: /* expr: expr tOR expr  */
+#line 827 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_or, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4450 "engines/director/lingo/lingo-gr.cpp"
+#line 4510 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 287: /* expr: expr '&' expr  */
-#line 824 "engines/director/lingo/lingo-gr.y"
+  case 291: /* expr: expr '&' expr  */
+#line 828 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_ampersand, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4456 "engines/director/lingo/lingo-gr.cpp"
+#line 4516 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 288: /* expr: expr tCONCAT expr  */
-#line 825 "engines/director/lingo/lingo-gr.y"
+  case 292: /* expr: expr tCONCAT expr  */
+#line 829 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_concat, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4462 "engines/director/lingo/lingo-gr.cpp"
+#line 4522 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 289: /* expr: expr tCONTAINS expr  */
-#line 826 "engines/director/lingo/lingo-gr.y"
+  case 293: /* expr: expr tCONTAINS expr  */
+#line 830 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_contains, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4468 "engines/director/lingo/lingo-gr.cpp"
+#line 4528 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 290: /* expr: expr tSTARTS expr  */
-#line 827 "engines/director/lingo/lingo-gr.y"
+  case 294: /* expr: expr tSTARTS expr  */
+#line 831 "engines/director/lingo/lingo-gr.y"
                                         { (yyval.node) = new BinaryOpNode(LC::c_starts, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4474 "engines/director/lingo/lingo-gr.cpp"
+#line 4534 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 293: /* expr_nounarymath: expr_nounarymath '+' expr  */
-#line 836 "engines/director/lingo/lingo-gr.y"
+  case 297: /* expr_nounarymath: expr_nounarymath '+' expr  */
+#line 840 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_add, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4480 "engines/director/lingo/lingo-gr.cpp"
+#line 4540 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 294: /* expr_nounarymath: expr_nounarymath '-' expr  */
-#line 837 "engines/director/lingo/lingo-gr.y"
+  case 298: /* expr_nounarymath: expr_nounarymath '-' expr  */
+#line 841 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_sub, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4486 "engines/director/lingo/lingo-gr.cpp"
+#line 4546 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 295: /* expr_nounarymath: expr_nounarymath '*' expr  */
-#line 838 "engines/director/lingo/lingo-gr.y"
+  case 299: /* expr_nounarymath: expr_nounarymath '*' expr  */
+#line 842 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_mul, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4492 "engines/director/lingo/lingo-gr.cpp"
+#line 4552 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 296: /* expr_nounarymath: expr_nounarymath '/' expr  */
-#line 839 "engines/director/lingo/lingo-gr.y"
+  case 300: /* expr_nounarymath: expr_nounarymath '/' expr  */
+#line 843 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_div, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4498 "engines/director/lingo/lingo-gr.cpp"
+#line 4558 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 297: /* expr_nounarymath: expr_nounarymath tMOD expr  */
-#line 840 "engines/director/lingo/lingo-gr.y"
+  case 301: /* expr_nounarymath: expr_nounarymath tMOD expr  */
+#line 844 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_mod, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4504 "engines/director/lingo/lingo-gr.cpp"
+#line 4564 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 298: /* expr_nounarymath: expr_nounarymath '>' expr  */
-#line 841 "engines/director/lingo/lingo-gr.y"
+  case 302: /* expr_nounarymath: expr_nounarymath '>' expr  */
+#line 845 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_gt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4510 "engines/director/lingo/lingo-gr.cpp"
+#line 4570 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 299: /* expr_nounarymath: expr_nounarymath '<' expr  */
-#line 842 "engines/director/lingo/lingo-gr.y"
+  case 303: /* expr_nounarymath: expr_nounarymath '<' expr  */
+#line 846 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_lt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4516 "engines/director/lingo/lingo-gr.cpp"
+#line 4576 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 300: /* expr_nounarymath: expr_nounarymath tEQ expr  */
-#line 843 "engines/director/lingo/lingo-gr.y"
+  case 304: /* expr_nounarymath: expr_nounarymath tEQ expr  */
+#line 847 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_eq, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4522 "engines/director/lingo/lingo-gr.cpp"
+#line 4582 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 301: /* expr_nounarymath: expr_nounarymath tNEQ expr  */
-#line 844 "engines/director/lingo/lingo-gr.y"
+  case 305: /* expr_nounarymath: expr_nounarymath tNEQ expr  */
+#line 848 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_neq, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4528 "engines/director/lingo/lingo-gr.cpp"
+#line 4588 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 302: /* expr_nounarymath: expr_nounarymath tGE expr  */
-#line 845 "engines/director/lingo/lingo-gr.y"
+  case 306: /* expr_nounarymath: expr_nounarymath tGE expr  */
+#line 849 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_ge, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4534 "engines/director/lingo/lingo-gr.cpp"
+#line 4594 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 303: /* expr_nounarymath: expr_nounarymath tLE expr  */
-#line 846 "engines/director/lingo/lingo-gr.y"
+  case 307: /* expr_nounarymath: expr_nounarymath tLE expr  */
+#line 850 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_le, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4540 "engines/director/lingo/lingo-gr.cpp"
+#line 4600 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 304: /* expr_nounarymath: expr_nounarymath tAND expr  */
-#line 847 "engines/director/lingo/lingo-gr.y"
+  case 308: /* expr_nounarymath: expr_nounarymath tAND expr  */
+#line 851 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_and, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4546 "engines/director/lingo/lingo-gr.cpp"
+#line 4606 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 305: /* expr_nounarymath: expr_nounarymath tOR expr  */
-#line 848 "engines/director/lingo/lingo-gr.y"
+  case 309: /* expr_nounarymath: expr_nounarymath tOR expr  */
+#line 852 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_or, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4552 "engines/director/lingo/lingo-gr.cpp"
+#line 4612 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 306: /* expr_nounarymath: expr_nounarymath '&' expr  */
-#line 849 "engines/director/lingo/lingo-gr.y"
+  case 310: /* expr_nounarymath: expr_nounarymath '&' expr  */
+#line 853 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_ampersand, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4558 "engines/director/lingo/lingo-gr.cpp"
+#line 4618 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 307: /* expr_nounarymath: expr_nounarymath tCONCAT expr  */
-#line 850 "engines/director/lingo/lingo-gr.y"
+  case 311: /* expr_nounarymath: expr_nounarymath tCONCAT expr  */
+#line 854 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new BinaryOpNode(LC::c_concat, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4564 "engines/director/lingo/lingo-gr.cpp"
+#line 4624 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 308: /* expr_nounarymath: expr_nounarymath tCONTAINS expr  */
-#line 851 "engines/director/lingo/lingo-gr.y"
+  case 312: /* expr_nounarymath: expr_nounarymath tCONTAINS expr  */
+#line 855 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new BinaryOpNode(LC::c_contains, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4570 "engines/director/lingo/lingo-gr.cpp"
+#line 4630 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 309: /* expr_nounarymath: expr_nounarymath tSTARTS expr  */
-#line 852 "engines/director/lingo/lingo-gr.y"
+  case 313: /* expr_nounarymath: expr_nounarymath tSTARTS expr  */
+#line 856 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new BinaryOpNode(LC::c_starts, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4576 "engines/director/lingo/lingo-gr.cpp"
+#line 4636 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 312: /* expr_noeq: expr_noeq '+' expr_noeq  */
-#line 857 "engines/director/lingo/lingo-gr.y"
+  case 316: /* expr_noeq: expr_noeq '+' expr_noeq  */
+#line 861 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_add, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4582 "engines/director/lingo/lingo-gr.cpp"
+#line 4642 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 313: /* expr_noeq: expr_noeq '-' expr_noeq  */
-#line 858 "engines/director/lingo/lingo-gr.y"
+  case 317: /* expr_noeq: expr_noeq '-' expr_noeq  */
+#line 862 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_sub, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4588 "engines/director/lingo/lingo-gr.cpp"
+#line 4648 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 314: /* expr_noeq: expr_noeq '*' expr_noeq  */
-#line 859 "engines/director/lingo/lingo-gr.y"
+  case 318: /* expr_noeq: expr_noeq '*' expr_noeq  */
+#line 863 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_mul, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4594 "engines/director/lingo/lingo-gr.cpp"
+#line 4654 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 315: /* expr_noeq: expr_noeq '/' expr_noeq  */
-#line 860 "engines/director/lingo/lingo-gr.y"
+  case 319: /* expr_noeq: expr_noeq '/' expr_noeq  */
+#line 864 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_div, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4600 "engines/director/lingo/lingo-gr.cpp"
+#line 4660 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 316: /* expr_noeq: expr_noeq tMOD expr_noeq  */
-#line 861 "engines/director/lingo/lingo-gr.y"
+  case 320: /* expr_noeq: expr_noeq tMOD expr_noeq  */
+#line 865 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_mod, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4606 "engines/director/lingo/lingo-gr.cpp"
+#line 4666 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 317: /* expr_noeq: expr_noeq '>' expr_noeq  */
-#line 862 "engines/director/lingo/lingo-gr.y"
+  case 321: /* expr_noeq: expr_noeq '>' expr_noeq  */
+#line 866 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_gt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4612 "engines/director/lingo/lingo-gr.cpp"
+#line 4672 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 318: /* expr_noeq: expr_noeq '<' expr_noeq  */
-#line 863 "engines/director/lingo/lingo-gr.y"
+  case 322: /* expr_noeq: expr_noeq '<' expr_noeq  */
+#line 867 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_lt, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4618 "engines/director/lingo/lingo-gr.cpp"
+#line 4678 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 319: /* expr_noeq: expr_noeq tNEQ expr_noeq  */
-#line 864 "engines/director/lingo/lingo-gr.y"
+  case 323: /* expr_noeq: expr_noeq tNEQ expr_noeq  */
+#line 868 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_neq, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4624 "engines/director/lingo/lingo-gr.cpp"
+#line 4684 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 320: /* expr_noeq: expr_noeq tGE expr_noeq  */
-#line 865 "engines/director/lingo/lingo-gr.y"
+  case 324: /* expr_noeq: expr_noeq tGE expr_noeq  */
+#line 869 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_ge, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4630 "engines/director/lingo/lingo-gr.cpp"
+#line 4690 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 321: /* expr_noeq: expr_noeq tLE expr_noeq  */
-#line 866 "engines/director/lingo/lingo-gr.y"
+  case 325: /* expr_noeq: expr_noeq tLE expr_noeq  */
+#line 870 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_le, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4636 "engines/director/lingo/lingo-gr.cpp"
+#line 4696 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 322: /* expr_noeq: expr_noeq tAND expr_noeq  */
-#line 867 "engines/director/lingo/lingo-gr.y"
+  case 326: /* expr_noeq: expr_noeq tAND expr_noeq  */
+#line 871 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_and, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4642 "engines/director/lingo/lingo-gr.cpp"
+#line 4702 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 323: /* expr_noeq: expr_noeq tOR expr_noeq  */
-#line 868 "engines/director/lingo/lingo-gr.y"
+  case 327: /* expr_noeq: expr_noeq tOR expr_noeq  */
+#line 872 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_or, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4648 "engines/director/lingo/lingo-gr.cpp"
+#line 4708 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 324: /* expr_noeq: expr_noeq '&' expr_noeq  */
-#line 869 "engines/director/lingo/lingo-gr.y"
+  case 328: /* expr_noeq: expr_noeq '&' expr_noeq  */
+#line 873 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_ampersand, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4654 "engines/director/lingo/lingo-gr.cpp"
+#line 4714 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 325: /* expr_noeq: expr_noeq tCONCAT expr_noeq  */
-#line 870 "engines/director/lingo/lingo-gr.y"
+  case 329: /* expr_noeq: expr_noeq tCONCAT expr_noeq  */
+#line 874 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_concat, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4660 "engines/director/lingo/lingo-gr.cpp"
+#line 4720 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 326: /* expr_noeq: expr_noeq tCONTAINS expr_noeq  */
-#line 871 "engines/director/lingo/lingo-gr.y"
+  case 330: /* expr_noeq: expr_noeq tCONTAINS expr_noeq  */
+#line 875 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new BinaryOpNode(LC::c_contains, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4666 "engines/director/lingo/lingo-gr.cpp"
+#line 4726 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 327: /* expr_noeq: expr_noeq tSTARTS expr_noeq  */
-#line 872 "engines/director/lingo/lingo-gr.y"
+  case 331: /* expr_noeq: expr_noeq tSTARTS expr_noeq  */
+#line 876 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new BinaryOpNode(LC::c_starts, (yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4672 "engines/director/lingo/lingo-gr.cpp"
+#line 4732 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 328: /* sprite: tSPRITE expr tINTERSECTS simpleexpr  */
-#line 875 "engines/director/lingo/lingo-gr.y"
+  case 332: /* sprite: tSPRITE expr tINTERSECTS simpleexpr  */
+#line 879 "engines/director/lingo/lingo-gr.y"
                                                 { (yyval.node) = new IntersectsNode((yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4678 "engines/director/lingo/lingo-gr.cpp"
+#line 4738 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 329: /* sprite: tSPRITE expr tWITHIN simpleexpr  */
-#line 876 "engines/director/lingo/lingo-gr.y"
+  case 333: /* sprite: tSPRITE expr tWITHIN simpleexpr  */
+#line 880 "engines/director/lingo/lingo-gr.y"
                                                         { (yyval.node) = new WithinNode((yyvsp[-2].node), (yyvsp[0].node)); }
-#line 4684 "engines/director/lingo/lingo-gr.cpp"
+#line 4744 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 330: /* exprlist: %empty  */
-#line 879 "engines/director/lingo/lingo-gr.y"
+  case 334: /* exprlist: %empty  */
+#line 883 "engines/director/lingo/lingo-gr.y"
                                                                 { (yyval.nodelist) = new NodeList; }
-#line 4690 "engines/director/lingo/lingo-gr.cpp"
+#line 4750 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 332: /* nonemptyexprlist: expr  */
-#line 883 "engines/director/lingo/lingo-gr.y"
+  case 336: /* nonemptyexprlist: expr  */
+#line 887 "engines/director/lingo/lingo-gr.y"
                                                         {
 		NodeList *list = new NodeList;
 		list->push_back((yyvsp[0].node));
 		(yyval.nodelist) = list; }
-#line 4699 "engines/director/lingo/lingo-gr.cpp"
+#line 4759 "engines/director/lingo/lingo-gr.cpp"
     break;
 
-  case 333: /* nonemptyexprlist: nonemptyexprlist ',' expr  */
-#line 887 "engines/director/lingo/lingo-gr.y"
+  case 337: /* nonemptyexprlist: nonemptyexprlist ',' expr  */
+#line 891 "engines/director/lingo/lingo-gr.y"
                                                 {
 		(yyvsp[-2].nodelist)->push_back((yyvsp[0].node));
 		(yyval.nodelist) = (yyvsp[-2].nodelist); }
-#line 4707 "engines/director/lingo/lingo-gr.cpp"
+#line 4767 "engines/director/lingo/lingo-gr.cpp"
     break;
 
 
-#line 4711 "engines/director/lingo/lingo-gr.cpp"
+#line 4771 "engines/director/lingo/lingo-gr.cpp"
 
       default: break;
     }
@@ -4905,7 +4965,7 @@ yyreturnlab:
   return yyresult;
 }
 
-#line 892 "engines/director/lingo/lingo-gr.y"
+#line 896 "engines/director/lingo/lingo-gr.y"
 
 
 int yyreport_syntax_error(const yypcontext_t *ctx) {
diff --git a/engines/director/lingo/lingo-gr.h b/engines/director/lingo/lingo-gr.h
index 73a80b0b7a0..c6ba1237d49 100644
--- a/engines/director/lingo/lingo-gr.h
+++ b/engines/director/lingo/lingo-gr.h
@@ -65,84 +65,86 @@ extern int yydebug;
     tFIELD = 266,                  /* tFIELD  */
     tSCRIPT = 267,                 /* tSCRIPT  */
     tWINDOW = 268,                 /* tWINDOW  */
-    tDELETE = 269,                 /* tDELETE  */
-    tDOWN = 270,                   /* tDOWN  */
-    tELSE = 271,                   /* tELSE  */
-    tEXIT = 272,                   /* tEXIT  */
-    tFRAME = 273,                  /* tFRAME  */
-    tGLOBAL = 274,                 /* tGLOBAL  */
-    tGO = 275,                     /* tGO  */
-    tHILITE = 276,                 /* tHILITE  */
-    tIF = 277,                     /* tIF  */
-    tIN = 278,                     /* tIN  */
-    tINTO = 279,                   /* tINTO  */
-    tMACRO = 280,                  /* tMACRO  */
-    tRETURN = 281,                 /* tRETURN  */
-    tMOVIE = 282,                  /* tMOVIE  */
-    tNEXT = 283,                   /* tNEXT  */
-    tOF = 284,                     /* tOF  */
-    tPREVIOUS = 285,               /* tPREVIOUS  */
-    tPUT = 286,                    /* tPUT  */
-    tREPEAT = 287,                 /* tREPEAT  */
-    tSET = 288,                    /* tSET  */
-    tTHEN = 289,                   /* tTHEN  */
-    tTO = 290,                     /* tTO  */
-    tWHEN = 291,                   /* tWHEN  */
-    tWITH = 292,                   /* tWITH  */
-    tWHILE = 293,                  /* tWHILE  */
-    tFACTORY = 294,                /* tFACTORY  */
-    tOPEN = 295,                   /* tOPEN  */
-    tPLAY = 296,                   /* tPLAY  */
-    tINSTANCE = 297,               /* tINSTANCE  */
-    tGE = 298,                     /* tGE  */
-    tLE = 299,                     /* tLE  */
-    tEQ = 300,                     /* tEQ  */
-    tNEQ = 301,                    /* tNEQ  */
-    tAND = 302,                    /* tAND  */
-    tOR = 303,                     /* tOR  */
-    tNOT = 304,                    /* tNOT  */
-    tMOD = 305,                    /* tMOD  */
-    tAFTER = 306,                  /* tAFTER  */
-    tBEFORE = 307,                 /* tBEFORE  */
-    tCONCAT = 308,                 /* tCONCAT  */
-    tCONTAINS = 309,               /* tCONTAINS  */
-    tSTARTS = 310,                 /* tSTARTS  */
-    tCHAR = 311,                   /* tCHAR  */
-    tCHARS = 312,                  /* tCHARS  */
-    tITEM = 313,                   /* tITEM  */
-    tITEMS = 314,                  /* tITEMS  */
-    tLINE = 315,                   /* tLINE  */
-    tLINES = 316,                  /* tLINES  */
-    tWORD = 317,                   /* tWORD  */
-    tWORDS = 318,                  /* tWORDS  */
-    tABBREVIATED = 319,            /* tABBREVIATED  */
-    tABBREV = 320,                 /* tABBREV  */
-    tABBR = 321,                   /* tABBR  */
-    tLONG = 322,                   /* tLONG  */
-    tSHORT = 323,                  /* tSHORT  */
-    tDATE = 324,                   /* tDATE  */
-    tLAST = 325,                   /* tLAST  */
-    tMENU = 326,                   /* tMENU  */
-    tMENUS = 327,                  /* tMENUS  */
-    tMENUITEM = 328,               /* tMENUITEM  */
-    tMENUITEMS = 329,              /* tMENUITEMS  */
-    tNUMBER = 330,                 /* tNUMBER  */
-    tTHE = 331,                    /* tTHE  */
-    tTIME = 332,                   /* tTIME  */
-    tXTRAS = 333,                  /* tXTRAS  */
-    tCASTLIBS = 334,               /* tCASTLIBS  */
-    tSOUND = 335,                  /* tSOUND  */
-    tSPRITE = 336,                 /* tSPRITE  */
-    tINTERSECTS = 337,             /* tINTERSECTS  */
-    tWITHIN = 338,                 /* tWITHIN  */
-    tTELL = 339,                   /* tTELL  */
-    tPROPERTY = 340,               /* tPROPERTY  */
-    tON = 341,                     /* tON  */
-    tMETHOD = 342,                 /* tMETHOD  */
-    tENDIF = 343,                  /* tENDIF  */
-    tENDREPEAT = 344,              /* tENDREPEAT  */
-    tENDTELL = 345,                /* tENDTELL  */
-    tASSERTERROR = 346             /* tASSERTERROR  */
+    tMEMBER = 269,                 /* tMEMBER  */
+    tCASTLIB = 270,                /* tCASTLIB  */
+    tDELETE = 271,                 /* tDELETE  */
+    tDOWN = 272,                   /* tDOWN  */
+    tELSE = 273,                   /* tELSE  */
+    tEXIT = 274,                   /* tEXIT  */
+    tFRAME = 275,                  /* tFRAME  */
+    tGLOBAL = 276,                 /* tGLOBAL  */
+    tGO = 277,                     /* tGO  */
+    tHILITE = 278,                 /* tHILITE  */
+    tIF = 279,                     /* tIF  */
+    tIN = 280,                     /* tIN  */
+    tINTO = 281,                   /* tINTO  */
+    tMACRO = 282,                  /* tMACRO  */
+    tRETURN = 283,                 /* tRETURN  */
+    tMOVIE = 284,                  /* tMOVIE  */
+    tNEXT = 285,                   /* tNEXT  */
+    tOF = 286,                     /* tOF  */
+    tPREVIOUS = 287,               /* tPREVIOUS  */
+    tPUT = 288,                    /* tPUT  */
+    tREPEAT = 289,                 /* tREPEAT  */
+    tSET = 290,                    /* tSET  */
+    tTHEN = 291,                   /* tTHEN  */
+    tTO = 292,                     /* tTO  */
+    tWHEN = 293,                   /* tWHEN  */
+    tWITH = 294,                   /* tWITH  */
+    tWHILE = 295,                  /* tWHILE  */
+    tFACTORY = 296,                /* tFACTORY  */
+    tOPEN = 297,                   /* tOPEN  */
+    tPLAY = 298,                   /* tPLAY  */
+    tINSTANCE = 299,               /* tINSTANCE  */
+    tGE = 300,                     /* tGE  */
+    tLE = 301,                     /* tLE  */
+    tEQ = 302,                     /* tEQ  */
+    tNEQ = 303,                    /* tNEQ  */
+    tAND = 304,                    /* tAND  */
+    tOR = 305,                     /* tOR  */
+    tNOT = 306,                    /* tNOT  */
+    tMOD = 307,                    /* tMOD  */
+    tAFTER = 308,                  /* tAFTER  */
+    tBEFORE = 309,                 /* tBEFORE  */
+    tCONCAT = 310,                 /* tCONCAT  */
+    tCONTAINS = 311,               /* tCONTAINS  */
+    tSTARTS = 312,                 /* tSTARTS  */
+    tCHAR = 313,                   /* tCHAR  */
+    tCHARS = 314,                  /* tCHARS  */
+    tITEM = 315,                   /* tITEM  */
+    tITEMS = 316,                  /* tITEMS  */
+    tLINE = 317,                   /* tLINE  */
+    tLINES = 318,                  /* tLINES  */
+    tWORD = 319,                   /* tWORD  */
+    tWORDS = 320,                  /* tWORDS  */
+    tABBREVIATED = 321,            /* tABBREVIATED  */
+    tABBREV = 322,                 /* tABBREV  */
+    tABBR = 323,                   /* tABBR  */
+    tLONG = 324,                   /* tLONG  */
+    tSHORT = 325,                  /* tSHORT  */
+    tDATE = 326,                   /* tDATE  */
+    tLAST = 327,                   /* tLAST  */
+    tMENU = 328,                   /* tMENU  */
+    tMENUS = 329,                  /* tMENUS  */
+    tMENUITEM = 330,               /* tMENUITEM  */
+    tMENUITEMS = 331,              /* tMENUITEMS  */
+    tNUMBER = 332,                 /* tNUMBER  */
+    tTHE = 333,                    /* tTHE  */
+    tTIME = 334,                   /* tTIME  */
+    tXTRAS = 335,                  /* tXTRAS  */
+    tCASTLIBS = 336,               /* tCASTLIBS  */
+    tSOUND = 337,                  /* tSOUND  */
+    tSPRITE = 338,                 /* tSPRITE  */
+    tINTERSECTS = 339,             /* tINTERSECTS  */
+    tWITHIN = 340,                 /* tWITHIN  */
+    tTELL = 341,                   /* tTELL  */
+    tPROPERTY = 342,               /* tPROPERTY  */
+    tON = 343,                     /* tON  */
+    tMETHOD = 344,                 /* tMETHOD  */
+    tENDIF = 345,                  /* tENDIF  */
+    tENDREPEAT = 346,              /* tENDREPEAT  */
+    tENDTELL = 347,                /* tENDTELL  */
+    tASSERTERROR = 348             /* tASSERTERROR  */
   };
   typedef enum yytokentype yytoken_kind_t;
 #endif
@@ -166,7 +168,7 @@ union YYSTYPE
 	Director::Node *node;
 	Director::NodeList *nodelist;
 
-#line 170 "engines/director/lingo/lingo-gr.h"
+#line 172 "engines/director/lingo/lingo-gr.h"
 
 };
 typedef union YYSTYPE YYSTYPE;
diff --git a/engines/director/lingo/lingo-gr.y b/engines/director/lingo/lingo-gr.y
index 684d3711363..3c89a2400f7 100644
--- a/engines/director/lingo/lingo-gr.y
+++ b/engines/director/lingo/lingo-gr.y
@@ -136,7 +136,7 @@ static void checkEnd(Common::String *token, Common::String *expect, bool require
 %token<f> tFLOAT
 %token<s> tVARID tSTRING tSYMBOL
 %token<s> tENDCLAUSE
-%token tCAST tFIELD tSCRIPT tWINDOW
+%token tCAST tFIELD tSCRIPT tWINDOW tMEMBER tCASTLIB
 %token tDELETE tDOWN tELSE tEXIT tFRAME tGLOBAL tGO tHILITE tIF tIN tINTO tMACRO tRETURN
 %token tMOVIE tNEXT tOF tPREVIOUS tPUT tREPEAT tSET tTHEN tTO tWHEN
 %token tWITH tWHILE tFACTORY tOPEN tPLAY tINSTANCE
@@ -310,6 +310,7 @@ CMDID: tVARID
 	| tAFTER		{ $$ = new Common::String("after"); }
 	| tBEFORE		{ $$ = new Common::String("before"); }
 	| tCAST			{ $$ = new Common::String("cast"); }
+	| tCASTLIB		{ $$ = new Common::String("castLib"); }
 	| tCHAR			{ $$ = new Common::String("char"); }
 	| tCHARS		{ $$ = new Common::String("chars"); }
 	| tDATE			{ $$ = new Common::String("date"); }
@@ -327,6 +328,7 @@ CMDID: tVARID
 	| tLINE			{ $$ = new Common::String("line"); }
 	| tLINES		{ $$ = new Common::String("lines"); }
 	| tLONG			{ $$ = new Common::String("long"); }
+	| tMEMBER		{ $$ = new Common::String("member"); }
 	| tMENU			{ $$ = new Common::String("menu"); }
 	| tMENUITEM		{ $$ = new Common::String("menuItem"); }
 	| tMENUITEMS	{ $$ = new Common::String("menuItems"); }
@@ -670,6 +672,8 @@ varorthe: var
 
 chunk: tFIELD refargs		{ $$ = new FuncNode(new Common::String("field"), $refargs); }
 	| tCAST refargs			{ $$ = new FuncNode(new Common::String("cast"), $refargs); }
+	| tMEMBER refargs		{ $$ = new FuncNode(new Common::String("member"), $refargs); }
+	| tCASTLIB refargs		{ $$ = new FuncNode(new Common::String("castLib"), $refargs); }
 	| tCHAR expr[idx] tOF simpleexpr[src]	{
 		$$ = new ChunkExprNode(kChunkChar, $idx, nullptr, $src); }
 	| tCHAR expr[start] tTO expr[end] tOF simpleexpr[src]	{
diff --git a/engines/director/lingo/lingo-lex.cpp b/engines/director/lingo/lingo-lex.cpp
index a43b84f3989..c5a66926f7b 100644
--- a/engines/director/lingo/lingo-lex.cpp
+++ b/engines/director/lingo/lingo-lex.cpp
@@ -355,8 +355,8 @@ static void yynoreturn yy_fatal_error ( const char* msg  );
 	(yy_hold_char) = *yy_cp; \
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
-#define YY_NUM_RULES 90
-#define YY_END_OF_BUFFER 91
+#define YY_NUM_RULES 92
+#define YY_END_OF_BUFFER 93
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -364,48 +364,48 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[366] =
+static const flex_int16_t yy_accept[370] =
     {   0,
-        0,    0,   91,   89,    1,   87,   87,   89,   89,   86,
-       86,   85,   86,   82,   86,   83,   83,   83,   83,   83,
-       83,   83,   83,   83,   83,   83,   83,   83,   83,   83,
-       83,   83,   83,   83,   83,   89,    1,   83,   89,    1,
-       87,    0,    0,   88,    2,   81,   84,   85,   80,   78,
-       79,   83,   83,   83,   83,   83,   83,   83,   83,   83,
-       83,   83,   83,   83,   83,   83,   83,   83,   24,   83,
-       26,   30,   83,   83,   83,   83,   83,   83,   83,   83,
-       83,   83,   48,   49,   83,   51,   83,   83,   83,   83,
-       83,   83,   83,   83,   83,   83,   83,   83,   83,   69,
-
-       83,   83,   83,   83,    1,    0,    0,   83,    2,   84,
-       83,   83,    7,   83,   83,   83,   83,   83,   83,   83,
-       83,   18,   83,   83,   83,   83,    0,    0,   83,   83,
-       83,   83,   83,   83,   83,   83,   83,   83,   43,   83,
-       83,   46,   83,   83,   83,   83,   83,   55,   83,   83,
-       83,   83,   60,   83,   83,   83,   83,   83,   66,   83,
-       83,   83,   83,   83,   83,   83,    0,   83,    5,   83,
-       83,    9,   11,   83,   14,   83,   16,   17,    0,    0,
-       19,   83,   83,   83,    0,   83,   83,   83,   29,   31,
-       33,   34,   36,   83,   38,   83,   83,   45,   83,   50,
-
-       52,   83,   83,   83,   83,   83,   83,   83,   83,   83,
-       83,   65,   67,   68,   83,   83,   83,   73,   75,   83,
-        0,   83,   83,    6,   83,   83,   12,   83,   83,   18,
-       21,   22,   83,   24,   83,   83,   83,   32,   35,   37,
-       83,   39,   83,   44,   83,   83,   83,   83,   83,   83,
-       83,   61,   62,   83,   83,    0,    0,   71,   83,   83,
-       76,   77,    0,   83,    4,    8,   83,   83,   15,   18,
-       23,   25,   83,   83,   83,   42,   47,   83,   83,   56,
-       57,   58,   83,   63,   64,    0,    0,    0,   72,   74,
-        0,   83,   83,   83,   83,   83,   83,   83,   83,   83,
-
-       83,    0,    0,    0,    0,   20,   83,   10,   13,   27,
-       83,   40,   53,   54,   83,    0,    0,    0,   20,   83,
-       83,   41,   83,    0,    0,    0,    0,   83,   28,   83,
-        0,    0,    0,    0,    3,   83,    0,    0,    0,    0,
-        0,    0,   83,    0,    0,    0,    0,    0,   83,    0,
-        0,   83,    0,    0,   83,    0,   83,   70,    0,   83,
-       70,   70,   70,   59,    0
+        0,    0,   93,   91,    1,   89,   89,   91,   91,   88,
+       88,   87,   88,   84,   88,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   91,    1,   85,   91,    1,
+       89,    0,    0,   90,    2,   83,   86,   87,   82,   80,
+       81,   85,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   25,   85,
+       27,   31,   85,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   50,   51,   85,   53,   85,   85,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   71,
+
+       85,   85,   85,   85,    1,    0,    0,   85,    2,   86,
+       85,   85,    7,   85,   85,   85,   85,   85,   85,   85,
+       85,   19,   85,   85,   85,   85,    0,    0,   85,   85,
+       85,   85,   85,   85,   85,   85,   85,   85,   85,   45,
+       85,   85,   48,   85,   85,   85,   85,   85,   57,   85,
+       85,   85,   85,   62,   85,   85,   85,   85,   85,   68,
+       85,   85,   85,   85,   85,   85,   85,    0,   85,    5,
+       85,   85,    9,   12,   85,   15,   85,   17,   18,    0,
+        0,   20,   85,   85,   85,    0,   85,   85,   85,   30,
+       32,   34,   35,   37,   85,   85,   40,   85,   85,   47,
+
+       85,   52,   54,   85,   85,   85,   85,   85,   85,   85,
+       85,   85,   85,   67,   69,   70,   85,   85,   85,   75,
+       77,   85,    0,   85,   85,    6,   85,   85,   13,   85,
+       85,   19,   22,   23,   85,   25,   85,   85,   85,   33,
+       36,   38,   85,   85,   41,   85,   46,   85,   85,   85,
+       85,   85,   85,   85,   63,   64,   85,   85,    0,    0,
+       73,   85,   85,   78,   79,    0,   85,    4,    8,   85,
+       85,   16,   19,   24,   26,   85,   85,   39,   85,   44,
+       49,   85,   85,   58,   59,   60,   85,   65,   66,    0,
+        0,    0,   74,   76,    0,   85,   85,   10,   85,   85,
+
+       85,   85,   85,   85,   85,    0,    0,    0,    0,   21,
+       85,   11,   14,   28,   85,   42,   55,   56,   85,    0,
+        0,    0,   21,   85,   85,   43,   85,    0,    0,    0,
+        0,   85,   29,   85,    0,    0,    0,    0,    3,   85,
+        0,    0,    0,    0,    0,    0,   85,    0,    0,    0,
+        0,    0,   85,    0,    0,   85,    0,    0,   85,    0,
+       85,   72,    0,   85,   72,   72,   72,   61,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -434,13 +434,13 @@ static const YY_CHAR yy_ec[256] =
 
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,   64,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[65] =
+static const YY_CHAR yy_meta[64] =
     {   0,
         1,    2,    3,    3,    2,    1,    1,    1,    1,    4,
         4,    1,    1,    1,    5,    5,    5,    5,    5,    5,
@@ -448,100 +448,100 @@ static const YY_CHAR yy_meta[65] =
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
         5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    1,    2,    2
+        5,    1,    2
     } ;
 
-static const flex_int16_t yy_base[373] =
+static const flex_int16_t yy_base[377] =
     {   0,
-        0,   63,  223,  855,   67,  855,  855,  211,    0,  855,
-      202,   56,   60,  855,  177,   59,   57,   62,   63,   60,
-       58,   64,   57,  101,    0,  109,  120,  117,  134,  142,
-       75,  183,  175,  185,   63,  127,  238,  215,  122,  245,
-      855,  120,  169,  855,    0,  855,  139,  112,  855,  855,
-      855,    0,  101,  110,  129,  133,  112,  140,  130,  137,
-      154,  147,  154,  177,  178,  191,  205,  163,  250,  202,
-        0,  224,  234,  213,  232,  233,  246,  237,  254,  230,
-      238,  247,    0,    0,  256,    0,  261,  276,  248,  273,
-      276,  259,  269,  277,  285,  302,  294,  299,  295,    0,
-
-      304,  303,  294,  301,  358,  325,   80,  327,    0,  129,
-      304,  327,    0,  320,  317,  321,  320,  337,  338,  337,
-      347,  369,  336,  351,  355,  351,  381,   75,  356,  351,
-      366,  360,  356,  374,  375,  370,  370,  377,    0,  383,
-      375,    0,  395,  385,  377,  381,  389,    0,  406,  394,
-      403,  402,    0,  403,  412,  418,  412,  420,  419,  429,
-      425,  428,  437,  434,  440,  444,  443,  429,  445,  436,
-      437,  445,  441,  459,    0,  445,    0,    0,  484,   71,
-        0,  457,  462,  472,  463,  460,  480,  466,    0,  468,
-        0,  470,    0,  474,  481,  477,  488,    0,  489,    0,
-
-        0,  486,  491,  499,  481,  487,  491,  488,  504,  494,
-      497,    0,    0,    0,  537,  518,  514,  522,  517,  519,
-      519,  525,  520,    0,  537,  534,    0,  535,  540,    0,
-        0,    0,  536,  855,  541,  535,  532,    0,    0,    0,
-      532,    0,  549,    0,  539,  542,  542,  543,  551,  556,
-      555,    0,    0,  549,  563,  617,   66,    0,  561,  570,
-        0,    0,  574,  573,  582,    0,  590,  580,    0,    0,
-        0,    0,  592,  591,  592,    0,    0,  580,  582,    0,
-        0,    0,  589,    0,    0,  598,  594,  601,    0,    0,
-      597,  594,  610,  604,  608,  626,  630,  616,  620,  615,
-
-      639,  618,  626,  634,  624,    0,  631,    0,    0,    0,
-      635,  638,    0,    0,  640,  640,  645,  667,  855,  669,
-      658,    0,  660,  665,  666,  679,  672,  681,    0,  683,
-      668,  701,  687,  673,    0,  677,  681,  723,   63,  682,
-      684,  683,  685,  731,  713,  684,  740,  744,  719,  728,
-      712,  719,  723,  750,  722,  752,  729,  764,   36,  729,
-        0,  770,   33,    0,  855,  834,   80,  836,  838,  842,
-      844,  849
+        0,   62,  472,  829,   66,  829,  829,  460,    0,  829,
+      436,   55,   59,  829,  425,   58,   56,   61,   62,   59,
+       57,   63,   56,   98,    0,  101,  108,  109,  137,  138,
+       74,  179,  181,  133,   64,  355,  130,  182,  243,  212,
+      829,  239,  252,  829,    0,  829,  240,   84,  829,  829,
+      829,    0,  105,  103,  104,  119,  139,  143,  148,  150,
+      158,  175,  186,  160,  196,  204,  211,  201,  235,  212,
+        0,  212,  220,  210,  218,  220,  232,  227,  239,  219,
+      226,  235,    0,    0,  233,    0,  249,  251,  233,  254,
+      259,  239,  257,  257,  261,  281,  273,  281,  275,    0,
+
+      285,  278,  281,  286,  334,  303,  127,  302,    0,  175,
+      290,  304,    0,  297,  294,  299,  300,  312,  322,  317,
+      327,  346,  319,  331,  331,  343,  358,  115,  338,  331,
+      343,  339,  334,  350,  353,  340,  360,  339,  355,    0,
+      356,  349,    0,  368,  360,  354,  364,  372,    0,  385,
+      372,  384,  383,    0,  381,  385,  393,  387,  393,  392,
+      404,  398,  401,  406,  408,  414,  419,  420,  406,  425,
+      415,  420,  426,  421,  440,    0,  424,    0,    0,  458,
+      113,    0,  441,  445,  450,  438,  437,  456,  442,    0,
+      445,    0,  446,    0,  452,  463,  462,  455,  467,    0,
+
+      468,    0,    0,  468,  473,  483,  466,  472,  476,  472,
+      481,  475,  479,    0,    0,    0,  522,  494,  489,  491,
+      487,  497,  497,  503,  498,    0,  515,  513,    0,  516,
+      521,    0,    0,    0,  517,  829,  525,  518,  515,    0,
+        0,    0,  517,  516,    0,  532,    0,  523,  528,  528,
+      528,  537,  534,  538,    0,    0,  532,  544,  576,  111,
+        0,  543,  555,    0,    0,  558,  558,  539,    0,  575,
+      565,    0,    0,    0,    0,  577,  576,    0,  578,    0,
+        0,  566,  571,    0,    0,    0,  578,    0,    0,  579,
+      578,  588,    0,    0,  577,  575,  599,  585,  588,  606,
+
+      612,  606,  602,  599,  626,  606,  611,  619,  609,    0,
+      615,    0,    0,    0,  617,  619,    0,    0,  620,  624,
+      622,  636,  829,  640,  629,    0,  630,  634,  634,  653,
+      647,  660,    0,  661,  646,  686,  672,  655,    0,  661,
+      665,  692,  108,  666,  668,  667,  668,  705,  681,  672,
+      715,  717,  690,  692,  685,  697,  702,  732,  707,  737,
+      711,  739,   82,  712,    0,  745,   79,    0,  829,  808,
+       79,  810,  812,  816,  818,  823
     } ;
 
-static const flex_int16_t yy_def[373] =
+static const flex_int16_t yy_def[377] =
     {   0,
-      365,    1,  365,  365,  365,  365,  365,  366,  367,  365,
-      365,  365,  365,  365,  365,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  365,  365,  368,  365,  365,
-      365,  365,  366,  365,  369,  365,  365,  365,  365,  365,
-      365,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-
-      368,  368,  368,  368,  365,  365,  365,  368,  369,  365,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  365,  365,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  365,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  370,  365,
-      368,  368,  368,  368,  365,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      365,  368,  368,  368,  368,  368,  368,  368,  368,  371,
-      368,  368,  368,  365,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  365,  365,  368,  368,  368,
-      368,  368,  365,  368,  368,  368,  368,  368,  368,  371,
-      368,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  365,  365,  365,  368,  368,
-      365,  368,  368,  368,  368,  368,  368,  368,  368,  368,
-
-      368,  365,  365,  365,  365,  368,  368,  368,  368,  368,
-      368,  368,  368,  368,  368,  365,  365,  365,  365,  368,
-      368,  368,  368,  365,  365,  365,  365,  368,  368,  368,
-      365,  365,  365,  365,  368,  368,  365,  365,  365,  365,
-      365,  365,  368,  365,  365,  365,  365,  365,  368,  365,
-      365,  368,  365,  365,  368,  365,  368,  372,  365,  368,
-      372,  372,  372,  368,    0,  365,  365,  365,  365,  365,
-      365,  365
+      369,    1,  369,  369,  369,  369,  369,  370,  371,  369,
+      369,  369,  369,  369,  369,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  369,  369,  372,  369,  369,
+      369,  369,  370,  369,  373,  369,  369,  369,  369,  369,
+      369,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+
+      372,  372,  372,  372,  369,  369,  369,  372,  373,  369,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  369,  369,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  369,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  374,
+      369,  372,  372,  372,  372,  369,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  369,  372,  372,  372,  372,  372,  372,  372,
+      372,  375,  372,  372,  372,  369,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  369,  369,
+      372,  372,  372,  372,  372,  369,  372,  372,  372,  372,
+      372,  372,  375,  372,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  369,
+      369,  369,  372,  372,  369,  372,  372,  372,  372,  372,
+
+      372,  372,  372,  372,  372,  369,  369,  369,  369,  372,
+      372,  372,  372,  372,  372,  372,  372,  372,  372,  369,
+      369,  369,  369,  372,  372,  372,  372,  369,  369,  369,
+      369,  372,  372,  372,  369,  369,  369,  369,  372,  372,
+      369,  369,  369,  369,  369,  369,  372,  369,  369,  369,
+      369,  369,  372,  369,  369,  372,  369,  369,  372,  369,
+      372,  376,  369,  372,  376,  376,  376,  372,    0,  369,
+      369,  369,  369,  369,  369,  369
     } ;
 
-static const flex_int16_t yy_nxt[920] =
+static const flex_int16_t yy_nxt[893] =
     {   0,
         4,    5,    6,    7,    5,    8,    9,   10,   11,    4,
        12,   13,   14,   15,   16,   17,   18,   19,   20,   21,
@@ -549,104 +549,102 @@ static const flex_int16_t yy_nxt[920] =
        31,   32,   33,   25,   25,   34,   35,   25,   16,   17,
        18,   19,   20,   21,   22,   23,   24,   25,   26,   27,
        28,   29,   30,   31,   32,   33,   25,   25,   34,   35,
-       25,    4,   36,   36,   37,   47,   48,   37,   40,   41,
-       41,   40,   49,   50,   53,   56,   57,   60,   54,   70,
-       66,   61,   38,   58,   45,   63,   55,   64,   67,   68,
-       59,   62,   69,   90,  362,  104,   65,  358,   53,   56,
-
-       57,   60,   54,   70,   66,   61,   38,   58,   63,   55,
-       64,   67,   68,   59,   62,   69,  111,   90,  104,   65,
-       71,   47,   48,   74,  338,   39,   39,  256,   72,   42,
-       42,   75,  179,   73,   77,   80,  127,   76,   78,  110,
-      111,  105,  112,  115,   71,   81,  113,   74,   79,  110,
-       82,   72,  114,   83,  116,   75,   73,  117,   77,   80,
-       76,   84,   78,   85,   86,  112,  115,   87,   81,  118,
-      113,   79,   88,   82,   44,   89,  114,   83,  116,  119,
-      117,   40,  120,  105,   84,  121,   85,   86,   40,   51,
-       87,  126,  118,   97,  122,   88,   98,   99,   89,   91,
-
-      123,   92,  119,  100,   93,  120,  101,  102,  121,  124,
-       46,   94,   95,  103,  126,   96,   44,   97,  122,  125,
-       98,   99,  365,   91,  123,   92,  100,  129,   93,  108,
-      101,  102,  365,  124,   94,   95,  103,   66,   96,  105,
-       41,   41,  105,  125,  133,   67,   40,   41,   41,   40,
-      129,  127,  132,  108,  127,  130,  131,  106,  365,  134,
-      135,   66,  136,  365,  137,  365,  141,  133,   67,  138,
-      142,  139,  365,  143,  144,  145,  132,  365,  130,  131,
-      148,  106,  134,  135,  365,  365,  136,  137,  140,  141,
-      365,  153,  138,  142,  146,  139,  143,  154,  144,  145,
-
-      107,  107,  149,  148,  147,  150,  151,   42,   42,  152,
-      155,  140,  128,  128,  153,  156,  157,  159,  146,  158,
-      154,  160,  161,  365,  165,  149,  162,  147,  150,  151,
-      163,  166,  152,  155,  169,  164,  365,  365,  156,  167,
-      157,  159,  158,  168,  160,  170,  161,  165,  171,  172,
-      162,  173,  174,  163,  166,  175,  176,  169,  164,  105,
-       41,   41,  105,  167,  177,  178,  184,  168,  181,  170,
-      179,  171,  172,  179,  173,  174,  182,  106,  186,  175,
-      176,  183,  127,  187,  188,  127,  190,  177,  191,  178,
-      184,  181,  192,  365,  189,  193,  365,  365,  196,  182,
-
-      194,  106,  186,  195,  183,  197,  187,  198,  188,  190,
-      199,  191,  200,  185,  201,  202,  192,  189,  203,  193,
-      107,  107,  196,  194,  204,  206,  195,  205,  207,  197,
-      198,  180,  180,  208,  199,  200,  185,  201,  202,  209,
-      210,  203,  211,  128,  128,  212,  213,  214,  204,  206,
-      205,  207,  215,  216,  217,  218,  208,  219,  220,  221,
-      365,  222,  209,  223,  210,  211,  224,  225,  212,  213,
-      226,  214,  227,  228,  231,  215,  216,  229,  217,  218,
-      232,  219,  220,  221,  222,  179,  233,  223,  179,  224,
-      225,  234,  235,  226,  236,  227,  237,  228,  231,  238,
-
-      229,  239,  240,  241,  232,  243,  244,  245,  246,  247,
-      233,  249,  242,  248,  234,  235,  250,  251,  236,  237,
-      252,  253,  238,  365,  239,  240,  254,  241,  243,  255,
-      244,  245,  246,  247,  249,  242,  258,  248,  256,  250,
-      251,  256,  259,  252,  260,  253,  180,  180,  261,  254,
-      262,  263,  255,  264,  265,  266,  267,  268,  269,  272,
-      258,  271,  273,  274,  275,  259,  276,  284,  260,  277,
-      278,  261,  279,  262,  263,  280,  264,  265,  281,  266,
-      267,  268,  269,  272,  271,  273,  274,  275,  282,  283,
-      276,  284,  277,  278,  285,  279,  289,  290,  280,  257,
-
-      257,  281,  291,  292,  293,  294,  365,  295,  296,  297,
-      298,  282,  283,  299,  300,  301,  302,  285,  256,  289,
-      290,  256,  303,  304,  307,  291,  292,  305,  293,  294,
-      295,  306,  296,  297,  298,  308,  299,  300,  301,  309,
-      302,  286,  312,  287,  310,  303,  311,  304,  307,  288,
-      305,  313,  314,  315,  306,  316,  365,  324,  308,  317,
-      318,  319,  309,  320,  286,  312,  287,  321,  310,  322,
-      311,  323,  288,  325,  313,  314,  326,  315,  316,  257,
-      257,  324,  317,  318,  319,  327,  320,  328,  365,  329,
-      321,  330,  322,  331,  323,  332,  325,  333,  335,  326,
-
-      334,  336,  338,  337,  340,  338,  342,  343,  344,  327,
-      346,  328,  329,  347,  330,  348,  331,  349,  332,  351,
-      341,  333,  335,  334,  338,  336,  337,  338,  340,  342,
-      343,  344,  338,  346,  350,  338,  347,  352,  348,  354,
-      349,  338,  351,  341,  338,  338,  353,  365,  338,  355,
-      356,  338,  357,  358,  338,  345,  358,  360,  350,  364,
-      365,  352,  354,  339,  339,  362,  365,  365,  362,  365,
-      353,  362,  355,  356,  362,  357,  365,  365,  345,  365,
-      360,  365,  364,  365,  365,  339,  339,  365,  365,  365,
-      365,  365,  365,  339,  339,  365,  365,  365,  365,  365,
-
-      365,  365,  339,  339,  365,  365,  339,  339,  365,  365,
-      365,  365,  339,  339,  359,  359,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  363,  363,  365,  365,
-      365,  365,  363,  363,   43,   43,  365,   43,   43,   52,
-       52,  109,  109,  230,  365,  365,  230,  270,  270,  361,
-      361,  365,  361,  361,    3,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365
+       25,    4,   36,   37,   47,   48,   37,   40,   41,   41,
+       40,   49,   50,   53,   56,   57,   60,   54,   70,   66,
+       61,   38,   58,   45,   63,   55,   64,   67,   68,   59,
+       62,   69,   90,   47,   48,   65,  104,   53,   56,   57,
+
+       60,   54,   70,   66,   61,   38,   58,   63,   55,   64,
+       67,   68,   59,   62,   69,   74,   90,   71,   65,  104,
+      111,  113,   77,   75,   39,   72,   78,   80,   42,   76,
+       73,  105,   41,   41,  105,  112,   79,   81,  114,   74,
+      366,   71,   82,  362,  111,  113,   77,   75,   72,  106,
+       78,   80,   76,   73,  101,  102,   83,  116,  112,   79,
+       81,  103,  114,   87,   84,   82,   85,   86,   88,  342,
+      115,   89,  259,  106,  180,  117,  127,  122,  101,  102,
+       83,  116,  118,  119,  103,  110,   87,   84,  105,   85,
+       86,   88,  107,  115,   89,   91,  108,   92,  117,   97,
+
+       93,  122,   98,   99,   66,  118,  119,   94,   95,  100,
+      120,   96,   67,   40,   41,   41,   40,  121,  123,   91,
+      108,   92,  124,   97,   93,  125,   98,   99,   66,  126,
+       94,   95,  100,  120,   96,   67,  127,  129,  132,  127,
+      121,  133,  123,  130,  131,  134,  124,  135,  136,  125,
+      110,  145,  126,  137,  138,  142,  140,   44,  143,  139,
+      129,  144,  132,  146,  133,  149,  130,  131,  134,  147,
+      135,  154,  136,  141,   42,  145,  137,  138,  142,  148,
+      140,  143,  139,  150,  144,  155,  151,  146,  149,  152,
+      156,  157,  153,  147,  154,  158,  141,  128,  159,  160,
+
+       40,  161,  148,  162,  105,  164,  150,  163,  155,  151,
+      165,  166,  152,  156,  157,  153,  167,  168,  169,  158,
+      170,  159,  171,  160,  161,  172,  173,  162,  164,  174,
+      176,  163,  175,  165,  166,  105,   41,   41,  105,  167,
+      177,  168,  169,  170,  178,  179,  171,  180,  172,  173,
+      180,  182,  174,  106,  176,  175,  183,  184,  185,  127,
+      187,  189,  127,  188,  177,  191,  192,  178,  193,  179,
+      195,  190,  197,  194,  182,  196,  198,  106,  199,  183,
+      184,  200,  185,  201,  187,  189,  188,  202,  191,  192,
+      186,  203,  193,  195,  190,  197,  107,  194,  204,  196,
+
+      198,  205,  199,  206,  200,  207,  208,  201,  181,  209,
+      202,  210,  211,  186,  203,  212,   40,  213,  214,  215,
+      128,  204,  216,  219,  205,  217,  218,  206,  207,  220,
+      208,  221,  209,  222,  210,  211,  223,   51,  224,  212,
+      213,  214,  215,  225,   46,  226,  216,  219,  217,  218,
+      227,  228,  229,  220,  230,  221,  231,  222,  233,  180,
+      223,  224,  180,  234,  235,   44,  236,  225,  226,  237,
+      238,  369,  239,  227,  228,  229,  240,  241,  230,  231,
+      242,  243,  233,  246,  244,  247,  248,  234,  235,  236,
+      249,  250,  237,  245,  238,  239,  252,  251,  256,  240,
+
+      241,  253,  254,  242,  255,  243,  246,  257,  244,  247,
+      248,  258,  261,  263,  249,  250,  245,  262,  264,  252,
+      181,  251,  256,  259,  253,  254,  259,  255,  265,  266,
+      257,  267,  268,  269,  258,  270,  261,  263,  271,  272,
+      262,  264,  274,  275,  369,  276,  277,  278,  279,  280,
+      288,  265,  266,  281,  267,  268,  282,  269,  283,  270,
+      284,  297,  271,  272,  285,  274,  286,  275,  276,  277,
+      278,  279,  287,  280,  288,  289,  281,  259,  293,  282,
+      259,  283,  294,  284,  260,  297,  295,  285,  296,  286,
+      298,  369,  299,  300,  301,  287,  302,  306,  289,  303,
+
+      290,  293,  291,  304,  305,  294,  307,  309,  292,  295,
+      308,  296,  310,  311,  298,  299,  312,  300,  301,  313,
+      302,  306,  303,  290,  314,  291,  304,  305,  315,  307,
+      309,  292,  316,  317,  308,  310,  318,  311,  260,  312,
+      319,  328,  313,  320,  321,  322,  323,  324,  314,  325,
+      326,  327,  315,  330,  331,  316,  317,  329,  332,  318,
+      333,  334,  335,  336,  319,  328,  320,  321,  322,  323,
+      324,  337,  325,  326,  327,  338,  330,  339,  331,  340,
+      329,  341,  332,  333,  334,  335,  336,  342,  346,  344,
+      342,  347,  348,  342,  350,  337,  342,  351,  338,  352,
+
+      353,  339,  354,  340,  341,  345,  342,  355,  356,  342,
+      357,  346,  358,  344,  347,  348,  342,  350,  342,  342,
+      351,  342,  352,  353,  349,  369,  354,  359,  345,  360,
+      355,  369,  356,  342,  357,  358,  342,  361,  362,  364,
+      366,  362,  368,  366,  369,  369,  366,  349,  343,  366,
+      359,  369,  360,  369,  343,  369,  369,  369,  369,  369,
+      361,  369,  364,  369,  369,  368,  369,  343,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  343,  369,  343,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  343,  369,  369,  369,  369,  363,
+
+      369,  367,  369,  369,  369,  369,  369,  367,   43,   43,
+      369,   43,   43,   52,   52,  109,  109,  232,  369,  369,
+      232,  273,  273,  365,  365,  369,  365,  365,    3,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369
+
     } ;
 
-static const flex_int16_t yy_chk[920] =
+static const flex_int16_t yy_chk[893] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -654,101 +652,99 @@ static const flex_int16_t yy_chk[920] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    2,   12,   12,    2,    5,    5,
-        5,    5,   13,   13,   16,   17,   18,   19,   16,   23,
-       21,   19,    2,   18,  367,   20,   16,   20,   21,   22,
-       18,   19,   22,   31,  363,   35,   20,  359,   16,   17,
-
-       18,   19,   16,   23,   21,   19,    2,   18,   20,   16,
-       20,   21,   22,   18,   19,   22,   53,   31,   35,   20,
-       24,   48,   48,   26,  339,    2,    2,  257,   24,    5,
-        5,   26,  180,   24,   27,   28,  128,   26,   27,  110,
-       53,  107,   54,   57,   24,   28,   55,   26,   27,   47,
-       28,   24,   56,   29,   58,   26,   24,   59,   27,   28,
-       26,   29,   27,   29,   29,   54,   57,   30,   28,   60,
-       55,   27,   30,   28,   43,   30,   56,   29,   58,   61,
-       59,   42,   62,   39,   29,   63,   29,   29,   36,   15,
-       30,   68,   60,   33,   64,   30,   33,   33,   30,   32,
-
-       65,   32,   61,   33,   32,   62,   34,   34,   63,   66,
-       11,   32,   32,   34,   68,   32,    8,   33,   64,   67,
-       33,   33,    3,   32,   65,   32,   33,   70,   32,   38,
-       34,   34,    0,   66,   32,   32,   34,   38,   32,   37,
-       37,   37,   37,   67,   74,   38,   40,   40,   40,   40,
-       70,   69,   73,   38,   69,   72,   72,   37,    0,   75,
-       76,   38,   77,    0,   78,    0,   80,   74,   38,   78,
-       81,   79,    0,   82,   85,   87,   73,    0,   72,   72,
-       89,   37,   75,   76,    0,    0,   77,   78,   79,   80,
-        0,   92,   78,   81,   88,   79,   82,   93,   85,   87,
-
-       37,   37,   90,   89,   88,   90,   91,   40,   40,   91,
-       94,   79,   69,   69,   92,   95,   96,   98,   88,   97,
-       93,   99,  101,    0,  103,   90,  101,   88,   90,   91,
-      102,  104,   91,   94,  111,  102,    0,    0,   95,  106,
-       96,   98,   97,  108,   99,  112,  101,  103,  114,  115,
-      101,  116,  117,  102,  104,  118,  119,  111,  102,  105,
-      105,  105,  105,  106,  120,  121,  126,  108,  123,  112,
-      122,  114,  115,  122,  116,  117,  124,  105,  129,  118,
-      119,  125,  127,  130,  131,  127,  132,  120,  133,  121,
-      126,  123,  134,    0,  131,  135,    0,    0,  138,  124,
-
-      136,  105,  129,  137,  125,  140,  130,  141,  131,  132,
-      143,  133,  144,  127,  145,  146,  134,  131,  147,  135,
-      105,  105,  138,  136,  149,  151,  137,  150,  152,  140,
-      141,  122,  122,  154,  143,  144,  127,  145,  146,  155,
-      156,  147,  157,  127,  127,  158,  159,  160,  149,  151,
-      150,  152,  161,  162,  163,  164,  154,  165,  166,  167,
-        0,  168,  155,  169,  156,  157,  170,  171,  158,  159,
-      172,  160,  173,  174,  182,  161,  162,  176,  163,  164,
-      183,  165,  166,  167,  168,  179,  184,  169,  179,  170,
-      171,  185,  186,  172,  187,  173,  188,  174,  182,  190,
-
-      176,  192,  194,  195,  183,  196,  197,  199,  202,  203,
-      184,  205,  195,  204,  185,  186,  206,  207,  187,  188,
-      208,  209,  190,    0,  192,  194,  210,  195,  196,  211,
-      197,  199,  202,  203,  205,  195,  216,  204,  215,  206,
-      207,  215,  217,  208,  218,  209,  179,  179,  219,  210,
-      220,  221,  211,  222,  223,  225,  226,  228,  229,  235,
-      216,  233,  236,  237,  241,  217,  243,  254,  218,  245,
-      246,  219,  247,  220,  221,  248,  222,  223,  249,  225,
-      226,  228,  229,  235,  233,  236,  237,  241,  250,  251,
-      243,  254,  245,  246,  255,  247,  259,  260,  248,  215,
-
-      215,  249,  263,  264,  265,  267,    0,  268,  273,  274,
-      275,  250,  251,  278,  279,  283,  286,  255,  256,  259,
-      260,  256,  287,  288,  293,  263,  264,  291,  265,  267,
-      268,  292,  273,  274,  275,  294,  278,  279,  283,  295,
-      286,  256,  298,  256,  296,  287,  297,  288,  293,  256,
-      291,  299,  300,  301,  292,  302,    0,  316,  294,  303,
-      304,  305,  295,  307,  256,  298,  256,  311,  296,  312,
-      297,  315,  256,  316,  299,  300,  317,  301,  302,  256,
-      256,  316,  303,  304,  305,  318,  307,  320,    0,  321,
-      311,  323,  312,  324,  315,  325,  316,  326,  328,  317,
-
-      327,  330,  332,  331,  333,  332,  334,  336,  337,  318,
-      340,  320,  321,  341,  323,  342,  324,  343,  325,  346,
-      333,  326,  328,  327,  338,  330,  331,  338,  333,  334,
-      336,  337,  344,  340,  345,  344,  341,  349,  342,  351,
-      343,  347,  346,  333,  347,  348,  350,    0,  348,  352,
-      353,  354,  355,  356,  354,  338,  356,  357,  345,  360,
-        0,  349,  351,  332,  332,  358,    0,    0,  358,    0,
-      350,  362,  352,  353,  362,  355,    0,    0,  338,    0,
-      357,    0,  360,    0,    0,  338,  338,    0,    0,    0,
-        0,    0,    0,  344,  344,    0,    0,    0,    0,    0,
-
-        0,    0,  347,  347,    0,    0,  348,  348,    0,    0,
-        0,    0,  354,  354,  356,  356,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  358,  358,    0,    0,
-        0,    0,  362,  362,  366,  366,    0,  366,  366,  368,
-      368,  369,  369,  370,    0,    0,  370,  371,  371,  372,
-      372,    0,  372,  372,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-
-      365,  365,  365,  365,  365,  365,  365,  365,  365,  365,
-      365,  365,  365,  365,  365,  365,  365,  365,  365
+        1,    1,    1,    2,   12,   12,    2,    5,    5,    5,
+        5,   13,   13,   16,   17,   18,   19,   16,   23,   21,
+       19,    2,   18,  371,   20,   16,   20,   21,   22,   18,
+       19,   22,   31,   48,   48,   20,   35,   16,   17,   18,
+
+       19,   16,   23,   21,   19,    2,   18,   20,   16,   20,
+       21,   22,   18,   19,   22,   26,   31,   24,   20,   35,
+       53,   55,   27,   26,    2,   24,   27,   28,    5,   26,
+       24,   37,   37,   37,   37,   54,   27,   28,   56,   26,
+      367,   24,   28,  363,   53,   55,   27,   26,   24,   37,
+       27,   28,   26,   24,   34,   34,   29,   58,   54,   27,
+       28,   34,   56,   30,   29,   28,   29,   29,   30,  343,
+       57,   30,  260,   37,  181,   59,  128,   64,   34,   34,
+       29,   58,   60,   61,   34,  110,   30,   29,  107,   29,
+       29,   30,   37,   57,   30,   32,   38,   32,   59,   33,
+
+       32,   64,   33,   33,   38,   60,   61,   32,   32,   33,
+       62,   32,   38,   40,   40,   40,   40,   63,   65,   32,
+       38,   32,   66,   33,   32,   67,   33,   33,   38,   68,
+       32,   32,   33,   62,   32,   38,   69,   70,   73,   69,
+       63,   74,   65,   72,   72,   75,   66,   76,   77,   67,
+       47,   85,   68,   78,   78,   80,   79,   43,   81,   78,
+       70,   82,   73,   87,   74,   89,   72,   72,   75,   88,
+       76,   92,   77,   79,   40,   85,   78,   78,   80,   88,
+       79,   81,   78,   90,   82,   93,   90,   87,   89,   91,
+       94,   95,   91,   88,   92,   96,   79,   69,   97,   98,
+
+       42,   99,   88,  101,   39,  102,   90,  101,   93,   90,
+      102,  103,   91,   94,   95,   91,  104,  106,  108,   96,
+      111,   97,  112,   98,   99,  114,  115,  101,  102,  116,
+      118,  101,  117,  102,  103,  105,  105,  105,  105,  104,
+      119,  106,  108,  111,  120,  121,  112,  122,  114,  115,
+      122,  123,  116,  105,  118,  117,  124,  125,  126,  127,
+      129,  131,  127,  130,  119,  132,  133,  120,  134,  121,
+      136,  131,  138,  135,  123,  137,  139,  105,  141,  124,
+      125,  142,  126,  144,  129,  131,  130,  145,  132,  133,
+      127,  146,  134,  136,  131,  138,  105,  135,  147,  137,
+
+      139,  148,  141,  150,  142,  151,  152,  144,  122,  153,
+      145,  155,  156,  127,  146,  157,   36,  158,  159,  160,
+      127,  147,  161,  164,  148,  162,  163,  150,  151,  165,
+      152,  166,  153,  167,  155,  156,  168,   15,  169,  157,
+      158,  159,  160,  170,   11,  171,  161,  164,  162,  163,
+      172,  173,  174,  165,  175,  166,  177,  167,  183,  180,
+      168,  169,  180,  184,  185,    8,  186,  170,  171,  187,
+      188,    3,  189,  172,  173,  174,  191,  193,  175,  177,
+      195,  196,  183,  198,  197,  199,  201,  184,  185,  186,
+      204,  205,  187,  197,  188,  189,  207,  206,  211,  191,
+
+      193,  208,  209,  195,  210,  196,  198,  212,  197,  199,
+      201,  213,  218,  220,  204,  205,  197,  219,  221,  207,
+      180,  206,  211,  217,  208,  209,  217,  210,  222,  223,
+      212,  224,  225,  227,  213,  228,  218,  220,  230,  231,
+      219,  221,  235,  237,    0,  238,  239,  243,  244,  246,
+      257,  222,  223,  248,  224,  225,  249,  227,  250,  228,
+      251,  268,  230,  231,  252,  235,  253,  237,  238,  239,
+      243,  244,  254,  246,  257,  258,  248,  259,  262,  249,
+      259,  250,  263,  251,  217,  268,  266,  252,  267,  253,
+      270,    0,  271,  276,  277,  254,  279,  290,  258,  282,
+
+      259,  262,  259,  283,  287,  263,  291,  295,  259,  266,
+      292,  267,  296,  297,  270,  271,  298,  276,  277,  299,
+      279,  290,  282,  259,  300,  259,  283,  287,  301,  291,
+      295,  259,  302,  303,  292,  296,  304,  297,  259,  298,
+      305,  320,  299,  306,  307,  308,  309,  311,  300,  315,
+      316,  319,  301,  321,  322,  302,  303,  320,  324,  304,
+      325,  327,  328,  329,  305,  320,  306,  307,  308,  309,
+      311,  330,  315,  316,  319,  331,  321,  332,  322,  334,
+      320,  335,  324,  325,  327,  328,  329,  336,  338,  337,
+      336,  340,  341,  342,  344,  330,  342,  345,  331,  346,
+
+      347,  332,  349,  334,  335,  337,  348,  350,  353,  348,
+      354,  338,  355,  337,  340,  341,  351,  344,  352,  351,
+      345,  352,  346,  347,  342,    0,  349,  356,  337,  357,
+      350,    0,  353,  358,  354,  355,  358,  359,  360,  361,
+      362,  360,  364,  362,    0,    0,  366,  342,  336,  366,
+      356,    0,  357,    0,  342,    0,    0,    0,    0,    0,
+      359,    0,  361,    0,    0,  364,    0,  348,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  351,    0,  352,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  358,    0,    0,    0,    0,  360,
+
+        0,  362,    0,    0,    0,    0,    0,  366,  370,  370,
+        0,  370,  370,  372,  372,  373,  373,  374,    0,    0,
+      374,  375,  375,  376,  376,    0,  376,  376,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  369,  369,  369,
+      369,  369
+
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -911,8 +907,8 @@ static Common::String *readUntilNull(const char **ptr) {
 	return res;
 }
 
-#line 914 "engines/director/lingo/lingo-lex.cpp"
-#line 915 "engines/director/lingo/lingo-lex.cpp"
+#line 910 "engines/director/lingo/lingo-lex.cpp"
+#line 911 "engines/director/lingo/lingo-lex.cpp"
 
 #define INITIAL 0
 
@@ -1133,7 +1129,7 @@ YY_DECL
 #line 166 "engines/director/lingo/lingo-lex.l"
 
 
-#line 1136 "engines/director/lingo/lingo-lex.cpp"
+#line 1132 "engines/director/lingo/lingo-lex.cpp"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1161,13 +1157,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 366 )
+				if ( yy_current_state >= 370 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 365 );
+		while ( yy_current_state != 369 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 
@@ -1235,46 +1231,51 @@ YY_RULE_SETUP
 case 10:
 YY_RULE_SETUP
 #line 179 "engines/director/lingo/lingo-lex.l"
-{ count(); return tCASTLIBS; }	// D5
+{ count(); return tCASTLIB; }	// D5
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
 #line 180 "engines/director/lingo/lingo-lex.l"
-{ count(); return tCHAR; }		// D3
+{ count(); return tCASTLIBS; }	// D5
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
 #line 181 "engines/director/lingo/lingo-lex.l"
-{ count(); return tCHARS; }
+{ count(); return tCHAR; }		// D3
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
 #line 182 "engines/director/lingo/lingo-lex.l"
-{ count(); return tCONTAINS; }
+{ count(); return tCHARS; }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
 #line 183 "engines/director/lingo/lingo-lex.l"
-{ count(); return tDATE; }
+{ count(); return tCONTAINS; }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
 #line 184 "engines/director/lingo/lingo-lex.l"
-{ count(); return tDELETE; }
+{ count(); return tDATE; }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
 #line 185 "engines/director/lingo/lingo-lex.l"
-{ count(); return tDOWN; }
+{ count(); return tDELETE; }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
 #line 186 "engines/director/lingo/lingo-lex.l"
-{ count(); return tELSE; }
+{ count(); return tDOWN; }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
 #line 187 "engines/director/lingo/lingo-lex.l"
+{ count(); return tELSE; }
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 188 "engines/director/lingo/lingo-lex.l"
 {
 		count();
 
@@ -1293,264 +1294,269 @@ YY_RULE_SETUP
 		return tENDCLAUSE;
 	}
 	YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 204 "engines/director/lingo/lingo-lex.l"
-{ count(); return tEXIT; }
-	YY_BREAK
 case 20:
 YY_RULE_SETUP
 #line 205 "engines/director/lingo/lingo-lex.l"
-{ count(); return tFACTORY; }
+{ count(); return tEXIT; }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
 #line 206 "engines/director/lingo/lingo-lex.l"
-{ count(); return tFIELD; }
+{ count(); return tFACTORY; }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
 #line 207 "engines/director/lingo/lingo-lex.l"
-{ count(); return tFRAME; }
+{ count(); return tFIELD; }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
 #line 208 "engines/director/lingo/lingo-lex.l"
-{ count(); return tGLOBAL; }
+{ count(); return tFRAME; }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
 #line 209 "engines/director/lingo/lingo-lex.l"
-{ count(); return tGO; }
+{ count(); return tGLOBAL; }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
 #line 210 "engines/director/lingo/lingo-lex.l"
-{ count(); return tHILITE; }
+{ count(); return tGO; }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
 #line 211 "engines/director/lingo/lingo-lex.l"
-{ count(); return tIF; }
+{ count(); return tHILITE; }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
 #line 212 "engines/director/lingo/lingo-lex.l"
-{ count(); return tINSTANCE; }
+{ count(); return tIF; }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
 #line 213 "engines/director/lingo/lingo-lex.l"
-{ count(); return tINTERSECTS;}
+{ count(); return tINSTANCE; }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
 #line 214 "engines/director/lingo/lingo-lex.l"
-{ count(); return tINTO; }
+{ count(); return tINTERSECTS;}
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
 #line 215 "engines/director/lingo/lingo-lex.l"
-{ count(); return tIN; }
+{ count(); return tINTO; }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
 #line 216 "engines/director/lingo/lingo-lex.l"
-{ count(); return tITEM; }
+{ count(); return tIN; }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
 #line 217 "engines/director/lingo/lingo-lex.l"
-{ count(); return tITEMS; }
+{ count(); return tITEM; }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
 #line 218 "engines/director/lingo/lingo-lex.l"
-{ count(); return tLAST; }
+{ count(); return tITEMS; }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
 #line 219 "engines/director/lingo/lingo-lex.l"
-{ count(); return tLINE; }
+{ count(); return tLAST; }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
 #line 220 "engines/director/lingo/lingo-lex.l"
-{ count(); return tLINES; }
+{ count(); return tLINE; }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 221 "engines/director/lingo/lingo-lex.l"
-{ count(); return tLONG; }
+{ count(); return tLINES; }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
 #line 222 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMACRO; }
+{ count(); return tLONG; }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
 #line 223 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMENU; }
+{ count(); return tMACRO; }
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
 #line 224 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMENUS; }
+{ count(); return tMEMBER; }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 225 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMENUITEM;}
+{ count(); return tMENU; }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 226 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMENUITEMS; }
+{ count(); return tMENUS; }
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 227 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMETHOD; }
+{ count(); return tMENUITEM;}
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 228 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMOD;}
+{ count(); return tMENUITEMS; }
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 229 "engines/director/lingo/lingo-lex.l"
-{ count(); return tMOVIE; }
+{ count(); return tMETHOD; }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 230 "engines/director/lingo/lingo-lex.l"
-{ count(); return tNEXT; }
+{ count(); return tMOD;}
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 231 "engines/director/lingo/lingo-lex.l"
-{ count(); return tNOT; }
+{ count(); return tMOVIE; }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 232 "engines/director/lingo/lingo-lex.l"
-{ count(); return tNUMBER; }
+{ count(); return tNEXT; }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 233 "engines/director/lingo/lingo-lex.l"
-{ count(); return tOF; }
+{ count(); return tNOT; }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 234 "engines/director/lingo/lingo-lex.l"
-{ count(); return tON; }		// D3
+{ count(); return tNUMBER; }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 235 "engines/director/lingo/lingo-lex.l"
-{ count(); return tOPEN; }
+{ count(); return tOF; }
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 236 "engines/director/lingo/lingo-lex.l"
-{ count(); return tOR; }
+{ count(); return tON; }		// D3
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 237 "engines/director/lingo/lingo-lex.l"
-{ count(); return tPLAY; }
+{ count(); return tOPEN; }
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 238 "engines/director/lingo/lingo-lex.l"
-{ count(); return tPREVIOUS; }
+{ count(); return tOR; }
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 239 "engines/director/lingo/lingo-lex.l"
-{ count(); return tPROPERTY; }	// D4
+{ count(); return tPLAY; }
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 240 "engines/director/lingo/lingo-lex.l"
-{ count(); return tPUT; }
+{ count(); return tPREVIOUS; }
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 241 "engines/director/lingo/lingo-lex.l"
-{ count(); return tREPEAT; }
+{ count(); return tPROPERTY; }	// D4
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 242 "engines/director/lingo/lingo-lex.l"
-{ count(); return tRETURN; }
+{ count(); return tPUT; }
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 243 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSCRIPT; }
+{ count(); return tREPEAT; }
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 244 "engines/director/lingo/lingo-lex.l"
-{ count(); return tASSERTERROR; }
+{ count(); return tRETURN; }
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 245 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSET; }
+{ count(); return tSCRIPT; }
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 246 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSHORT; }
+{ count(); return tASSERTERROR; }
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 247 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSOUND; }
+{ count(); return tSET; }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 248 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSPRITE; }
+{ count(); return tSHORT; }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 249 "engines/director/lingo/lingo-lex.l"
-{ count(); return tSTARTS; }
+{ count(); return tSOUND; }
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 250 "engines/director/lingo/lingo-lex.l"
-{ count(); return tTELL; }
+{ count(); return tSPRITE; }
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 251 "engines/director/lingo/lingo-lex.l"
-{ count(); return tTHE; }
+{ count(); return tSTARTS; }
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 252 "engines/director/lingo/lingo-lex.l"
-{ count(); return tTHEN; }
+{ count(); return tTELL; }
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 253 "engines/director/lingo/lingo-lex.l"
-{ count(); return tTIME; }
+{ count(); return tTHE; }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 254 "engines/director/lingo/lingo-lex.l"
-{ count(); return tTO; }
+{ count(); return tTHEN; }
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 255 "engines/director/lingo/lingo-lex.l"
+{ count(); return tTIME; }
+	YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 256 "engines/director/lingo/lingo-lex.l"
+{ count(); return tTO; }
+	YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 257 "engines/director/lingo/lingo-lex.l"
 {
 		count();
 
@@ -1570,69 +1576,69 @@ YY_RULE_SETUP
 		return tWHEN;
 	}
 	YY_BREAK
-case 71:
-YY_RULE_SETUP
-#line 273 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWHILE; }
-	YY_BREAK
-case 72:
-YY_RULE_SETUP
-#line 274 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWINDOW; }
-	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 275 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWITH; }
+{ count(); return tWHILE; }
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 276 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWITHIN; }
+{ count(); return tWINDOW; }
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 277 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWORD; }
+{ count(); return tWITH; }
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 278 "engines/director/lingo/lingo-lex.l"
-{ count(); return tWORDS; }
+{ count(); return tWITHIN; }
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 279 "engines/director/lingo/lingo-lex.l"
-{ count(); return tXTRAS; } // D5
+{ count(); return tWORD; }
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 281 "engines/director/lingo/lingo-lex.l"
-{ count(); return tNEQ; }
+#line 280 "engines/director/lingo/lingo-lex.l"
+{ count(); return tWORDS; }
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 282 "engines/director/lingo/lingo-lex.l"
-{ count(); return tGE; }
+#line 281 "engines/director/lingo/lingo-lex.l"
+{ count(); return tXTRAS; } // D5
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 283 "engines/director/lingo/lingo-lex.l"
-{ count(); return tLE; }
+{ count(); return tNEQ; }
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 284 "engines/director/lingo/lingo-lex.l"
-{ count(); return tCONCAT; }
+{ count(); return tGE; }
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 285 "engines/director/lingo/lingo-lex.l"
-{ count(); return tEQ; }
+{ count(); return tLE; }
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
+#line 286 "engines/director/lingo/lingo-lex.l"
+{ count(); return tCONCAT; }
+	YY_BREAK
+case 84:
+YY_RULE_SETUP
 #line 287 "engines/director/lingo/lingo-lex.l"
+{ count(); return tEQ; }
+	YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 289 "engines/director/lingo/lingo-lex.l"
 {
 		count();
 		yylval.s = new Common::String(yytext);
@@ -1640,43 +1646,43 @@ YY_RULE_SETUP
 		return tVARID;
 	}
 	YY_BREAK
-case 84:
-YY_RULE_SETUP
-#line 293 "engines/director/lingo/lingo-lex.l"
-{ count(); yylval.f = atof(yytext); return tFLOAT; }
-	YY_BREAK
-case 85:
-YY_RULE_SETUP
-#line 294 "engines/director/lingo/lingo-lex.l"
-{ count(); yylval.i = strtol(yytext, NULL, 10); return tINT; }
-	YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 295 "engines/director/lingo/lingo-lex.l"
-{ count(); return *yytext; }
+{ count(); yylval.f = atof(yytext); return tFLOAT; }
 	YY_BREAK
 case 87:
-/* rule 87 can match eol */
 YY_RULE_SETUP
 #line 296 "engines/director/lingo/lingo-lex.l"
-{ count(); return '\n'; }
+{ count(); yylval.i = strtol(yytext, NULL, 10); return tINT; }
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 297 "engines/director/lingo/lingo-lex.l"
-{ count(); yylval.s = cleanupString(&yytext[1]); yylval.s->deleteLastChar(); return tSTRING; }
+{ count(); return *yytext; }
 	YY_BREAK
 case 89:
+/* rule 89 can match eol */
 YY_RULE_SETUP
 #line 298 "engines/director/lingo/lingo-lex.l"
-{ count(); }
+{ count(); return '\n'; }
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
+#line 299 "engines/director/lingo/lingo-lex.l"
+{ count(); yylval.s = cleanupString(&yytext[1]); yylval.s->deleteLastChar(); return tSTRING; }
+	YY_BREAK
+case 91:
+YY_RULE_SETUP
 #line 300 "engines/director/lingo/lingo-lex.l"
+{ count(); }
+	YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 302 "engines/director/lingo/lingo-lex.l"
 ECHO;
 	YY_BREAK
-#line 1679 "engines/director/lingo/lingo-lex.cpp"
+#line 1685 "engines/director/lingo/lingo-lex.cpp"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1975,7 +1981,7 @@ static int yy_get_next_buffer (void)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 366 )
+			if ( yy_current_state >= 370 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2003,11 +2009,11 @@ static int yy_get_next_buffer (void)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 366 )
+		if ( yy_current_state >= 370 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 365);
+	yy_is_jam = (yy_current_state == 369);
 
 		return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2648,7 +2654,7 @@ void yyfree (void * ptr )
 
 #define YYTABLES_NAME "yytables"
 
-#line 300 "engines/director/lingo/lingo-lex.l"
+#line 302 "engines/director/lingo/lingo-lex.l"
 
 
 extern int yydebug;
diff --git a/engines/director/lingo/lingo-lex.l b/engines/director/lingo/lingo-lex.l
index 00fb906b451..5a64738f5a8 100644
--- a/engines/director/lingo/lingo-lex.l
+++ b/engines/director/lingo/lingo-lex.l
@@ -176,6 +176,7 @@ after		{ count(); return tAFTER; }		// D3
 and			{ count(); return tAND; }
 before		{ count(); return tBEFORE; }	// D3
 cast		{ count(); return tCAST; }
+castlib		{ count(); return tCASTLIB; }	// D5
 castlibs	{ count(); return tCASTLIBS; }	// D5
 char		{ count(); return tCHAR; }		// D3
 chars		{ count(); return tCHARS; }
@@ -220,6 +221,7 @@ line		{ count(); return tLINE; }
 lines		{ count(); return tLINES; }
 long		{ count(); return tLONG; }
 macro		{ count(); return tMACRO; }
+member		{ count(); return tMEMBER; }
 menu		{ count(); return tMENU; }
 menus		{ count(); return tMENUS; }
 menuItem	{ count(); return tMENUITEM;}


Commit: afdc7a91faa43b7491f919b4e040898483e657a5
    https://github.com/scummvm/scummvm/commit/afdc7a91faa43b7491f919b4e040898483e657a5
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add entities/fields new to Director 5

Changed paths:
    engines/director/castmember/movie.cpp
    engines/director/castmember/movie.h
    engines/director/castmember/shape.cpp
    engines/director/castmember/shape.h
    engines/director/castmember/text.cpp
    engines/director/castmember/text.h
    engines/director/castmember/transition.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h
    engines/director/stxt.cpp
    engines/director/stxt.h
    engines/director/types.h


diff --git a/engines/director/castmember/movie.cpp b/engines/director/castmember/movie.cpp
index 65fa061536a..bb94fc2c910 100644
--- a/engines/director/castmember/movie.cpp
+++ b/engines/director/castmember/movie.cpp
@@ -22,6 +22,7 @@
 #include "director/director.h"
 #include "director/movie.h"
 #include "director/castmember/movie.h"
+#include "director/lingo/lingo-the.h"
 
 namespace Director {
 
@@ -63,6 +64,57 @@ MovieCastMember::MovieCastMember(Cast *cast, uint16 castId, MovieCastMember &sou
 	_center = source._center;
 }
 
+bool MovieCastMember::hasField(int field) {
+	switch (field) {
+	case kTheSound:
+	case kTheCenter:
+	case kTheScriptsEnabled:
+		return true;
+	default:
+		break;
+	}
+	return CastMember::hasField(field);
+}
+
+Datum MovieCastMember::getField(int field) {
+	Datum d;
+
+	switch (field) {
+	case kTheSound:
+		d = Datum(_enableSound);
+		break;
+	case kTheCenter:
+		d = Datum((int)_center);
+		break;
+	case kTheScriptsEnabled:
+		d = Datum(_enableScripts);
+		break;
+	default:
+		d = CastMember::getField(field);
+		break;
+	}
+
+	return d;
+}
+
+bool MovieCastMember::setField(int field, const Datum &d) {
+	switch (field) {
+	case kTheSound:
+		_enableSound = (bool)d.asInt();
+		return true;
+	case kTheCenter:
+		_center = (bool)d.asInt();
+		return true;
+	case kTheScriptsEnabled:
+		_enableScripts = (bool)d.asInt();
+		return true;
+	default:
+		break;
+	}
+
+	return CastMember::setField(field, d);
+}
+
 Common::String MovieCastMember::formatInfo() {
 	return Common::String::format(
 		"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, enableScripts: %d, enableSound: %d, looping: %d, crop: %d, center: %d",
diff --git a/engines/director/castmember/movie.h b/engines/director/castmember/movie.h
index ac4f293379c..5e84bb402ca 100644
--- a/engines/director/castmember/movie.h
+++ b/engines/director/castmember/movie.h
@@ -31,6 +31,10 @@ public:
 	MovieCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
 	MovieCastMember(Cast *cast, uint16 castId, MovieCastMember &source);
 
+	bool hasField(int field) override;
+	Datum getField(int field) override;
+	bool setField(int field, const Datum &value) override;
+
 	Common::String formatInfo() override;
 
 	uint32 _flags;
diff --git a/engines/director/castmember/shape.cpp b/engines/director/castmember/shape.cpp
index 7bcbb4030fa..4fcaf65a30f 100644
--- a/engines/director/castmember/shape.cpp
+++ b/engines/director/castmember/shape.cpp
@@ -22,6 +22,7 @@
 #include "director/director.h"
 #include "director/movie.h"
 #include "director/castmember/shape.h"
+#include "director/lingo/lingo-the.h"
 
 namespace Director {
 
@@ -107,6 +108,51 @@ void ShapeCastMember::setForeColor(uint32 fgCol) {
 	_modified = true;
 }
 
+bool ShapeCastMember::hasField(int field) {
+	switch (field) {
+	case kTheFilled:
+	case kTheLineSize:
+		return true;
+	default:
+		break;
+	}
+	return CastMember::hasField(field);
+}
+
+Datum ShapeCastMember::getField(int field) {
+	Datum d;
+
+	switch (field) {
+	case kTheFilled:
+		d = Datum((bool)_fillType);
+		break;
+	case kTheLineSize:
+		d = Datum(_lineThickness);
+		break;
+	default:
+		d = CastMember::getField(field);
+		break;
+	}
+
+	return d;
+}
+
+bool ShapeCastMember::setField(int field, const Datum &d) {
+	switch (field) {
+	case kTheFilled:
+		_fillType = d.asInt() ? 1 : 0;
+		return true;
+	case kTheLineSize:
+		_lineThickness = d.asInt();
+		return true;
+	default:
+		break;
+	}
+
+	return CastMember::setField(field, d);
+}
+
+
 Common::String ShapeCastMember::formatInfo() {
 	return Common::String::format(
 		"initialRect: %dx%d@%d,%d, boundingRect: %dx%d@%d,%d, foreColor: %d, backColor: %d, shapeType: %d, pattern: %d, fillType: %d, lineThickness: %d, lineDirection: %d, ink: %d",
diff --git a/engines/director/castmember/shape.h b/engines/director/castmember/shape.h
index 5e733d46256..345e40ab803 100644
--- a/engines/director/castmember/shape.h
+++ b/engines/director/castmember/shape.h
@@ -35,6 +35,10 @@ public:
 	void setBackColor(uint32 bgCol) override;
 	void setForeColor(uint32 fgCol) override;
 
+	bool hasField(int field) override;
+	Datum getField(int field) override;
+	bool setField(int field, const Datum &value) override;
+
 	Common::String formatInfo() override;
 
 	ShapeType _shapeType;
diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index 13f9277830f..87e9720536c 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -40,9 +40,9 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 		: CastMember(cast, castId, stream) {
 	_type = kCastText;
 
-	_borderSize = kSizeNone;
-	_gutterSize = kSizeNone;
-	_boxShadow = kSizeNone;
+	_borderSize = 0;
+	_gutterSize = 0;
+	_boxShadow = 0;
 	_buttonType = kTypeButton;
 	_editable = false;
 	_maxHeight = _textHeight = 0;
@@ -56,7 +56,7 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 	_fontSize = 12;
 	_textType = kTextTypeFixed;
 	_textAlign = kTextAlignLeft;
-	_textShadow = kSizeNone;
+	_textShadow = 0;
 	_textSlant = 0;
 	_bgpalinfo1 = _bgpalinfo2 = _bgpalinfo3 = 0;
 	_fgpalinfo1 = _fgpalinfo2 = _fgpalinfo3 = 0xff;
@@ -70,9 +70,9 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 
 	if (version < kFileVer400) {
 		_flags1 = flags1; // region: 0 - auto, 1 - matte, 2 - disabled
-		_borderSize = static_cast<SizeType>(stream.readByte());
-		_gutterSize = static_cast<SizeType>(stream.readByte());
-		_boxShadow = static_cast<SizeType>(stream.readByte());
+		_borderSize = stream.readByte();
+		_gutterSize = stream.readByte();
+		_boxShadow = stream.readByte();
 		_textType = static_cast<TextType>(stream.readByte());
 		_textAlign = static_cast<TextAlignType>(stream.readUint16());
 		_bgpalinfo1 = stream.readUint16();
@@ -93,7 +93,7 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 			_initialRect = Movie::readRect(stream);
 			pad3 = stream.readUint16();
 
-			_textShadow = static_cast<SizeType>(stream.readByte());
+			_textShadow = stream.readByte();
 			_textFlags = stream.readByte();
 			if (_textFlags & 0xf8)
 				warning("Unprocessed text cast flags: %x", _textFlags & 0xf8);
@@ -117,9 +117,9 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 		}
 	} else if (version >= kFileVer400 && version < kFileVer600) {
 		_flags1 = flags1;
-		_borderSize = static_cast<SizeType>(stream.readByte());
-		_gutterSize = static_cast<SizeType>(stream.readByte());
-		_boxShadow = static_cast<SizeType>(stream.readByte());
+		_borderSize = stream.readByte();
+		_gutterSize = stream.readByte();
+		_boxShadow = stream.readByte();
 		_textType = static_cast<TextType>(stream.readByte());
 		_textAlign = static_cast<TextAlignType>(stream.readSint16()); // this is because 'right' is -1? or should that be 255?
 		_bgpalinfo1 = stream.readUint16();
@@ -131,7 +131,7 @@ TextCastMember::TextCastMember(Cast *cast, uint16 castId, Common::SeekableReadSt
 
 		_initialRect = Movie::readRect(stream);
 		_maxHeight = stream.readUint16();
-		_textShadow = static_cast<SizeType>(stream.readByte());
+		_textShadow = stream.readByte();
 		_textFlags = stream.readByte(); // 1: editable, 2: auto tab 4: don't wrap
 		_editable = _textFlags & 0x1;
 
@@ -478,8 +478,12 @@ bool TextCastMember::hasField(int field) {
 	case kTheTextHeight:
 	case kTheTextSize:
 	case kTheTextStyle:
-	case kTheScrollTop:
 		return true;
+	case kTheBorder:
+	case kTheScrollTop:
+		return _type == kCastText;
+	case kTheButtonType:
+		return _type == kCastButton;
 	default:
 		break;
 	}
@@ -526,9 +530,29 @@ Datum TextCastMember::getField(int field) {
 	case kTheTextStyle:
 		d = (int)_textSlant;
 		break;
+	case kTheBorder:
+		d = _borderSize;
+		break;
 	case kTheScrollTop:
 		d = _scroll;
 		break;
+	case kTheButtonType:
+		switch (_buttonType) {
+		case kTypeCheckBox:
+			d = Datum("checkBox");
+			d.type = SYMBOL;
+			break;
+		case kTypeRadio:
+			d = Datum("radioButton");
+			d.type = SYMBOL;
+			break;
+		case kTypeButton:
+		default:
+			d = Datum("pushButton");
+			d.type = SYMBOL;
+			break;
+		}
+		break;
 	default:
 		d = CastMember::getField(field);
 	}
@@ -635,6 +659,28 @@ bool TextCastMember::setField(int field, const Datum &d) {
 	case kTheScrollTop:
 		_scroll = d.asInt();
 		return true;
+	case kTheBorder:
+		_borderSize = d.asInt();
+		setModified(true);
+		return true;
+	case kTheButtonType:
+		if (d.type == SYMBOL) {
+			if (d.u.s->equalsIgnoreCase("pushButton")) {
+				_buttonType = kTypeButton;
+				setModified(true);
+				return true;
+			} else if (d.u.s->equalsIgnoreCase("radioButton")) {
+				_buttonType = kTypeRadio;
+				setModified(true);
+				return true;
+			} else if (d.u.s->equalsIgnoreCase("checkBox")) {
+				_buttonType = kTypeCheckBox;
+				setModified(true);
+				return true;
+			}
+		}
+		warning("TextCastMember: invalid button type %s", d.asString(true).c_str());
+		return false;
 	default:
 		break;
 	}
diff --git a/engines/director/castmember/text.h b/engines/director/castmember/text.h
index 21600fef73d..fdac20b5ae0 100644
--- a/engines/director/castmember/text.h
+++ b/engines/director/castmember/text.h
@@ -62,9 +62,9 @@ public:
 	void load() override;
 	void unload() override;
 
-	SizeType _borderSize;
-	SizeType _gutterSize;
-	SizeType _boxShadow;
+	uint8 _borderSize;
+	uint8 _gutterSize;
+	uint8 _boxShadow;
 	uint16 _maxHeight;
 	uint16 _textHeight;
 
@@ -72,7 +72,7 @@ public:
 	uint16 _fontSize;
 	TextType _textType;
 	TextAlignType _textAlign;
-	SizeType _textShadow;
+	uint8 _textShadow;
 	uint16 _scroll;
 	byte _textSlant;
 	byte _textFlags;
diff --git a/engines/director/castmember/transition.cpp b/engines/director/castmember/transition.cpp
index 9e3690394d7..070dab5f24c 100644
--- a/engines/director/castmember/transition.cpp
+++ b/engines/director/castmember/transition.cpp
@@ -65,7 +65,9 @@ TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, Transition
 
 bool TransitionCastMember::hasField(int field) {
 	switch (field) {
+	case kTheChunkSize:
 	case kTheDuration:
+	case kTheTransitionType:
 		return true;
 	default:
 		break;
@@ -77,9 +79,15 @@ Datum TransitionCastMember::getField(int field) {
 	Datum d;
 
 	switch (field) {
+	case kTheChunkSize:
+		d = Datum(_chunkSize);
+		break;
 	case kTheDuration:
 		d = Datum(_durationMillis);
 		break;
+	case kTheTransitionType:
+		d = Datum((int)_transType);
+		break;
 	default:
 		d = CastMember::getField(field);
 		break;
@@ -90,9 +98,15 @@ Datum TransitionCastMember::getField(int field) {
 
 bool TransitionCastMember::setField(int field, const Datum &d) {
 	switch (field) {
+	case kTheChunkSize:
+		_chunkSize = d.asInt();
+		return true;
 	case kTheDuration:
 		_durationMillis = (bool)d.asInt();
 		return true;
+	case kTheTransitionType:
+		_transType = (TransitionType)d.asInt();
+		return true;
 	default:
 		break;
 	}
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 814c3f031fb..805e4748bf3 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3372,7 +3372,13 @@ void LB::b_cast(int nargs) {
 
 void LB::b_castLib(int nargs) {
 	Datum d = g_lingo->pop();
-	Datum res = d.asInt();
+	Datum res(0);
+	if (d.type == STRING) {
+		Movie *movie = g_director->getCurrentMovie();
+		res.u.i = movie->getCastLibIDByName(*d.u.s);
+	} else {
+		res.u.i = d.asInt();
+	}
 	res.type = CASTLIBREF;
 	g_lingo->push(res);
 }
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index e8bdba3a7ea..af1c5de4edf 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -212,8 +212,13 @@ static const LingoV4TheEntity lingoV4TheEntity[] = {
 	{ 0x06, 0x21, kTheSprite,			kTheLoc,			true, kTEAItemId },
 	{ 0x06, 0x22, kTheSprite,			kTheRect,			true, kTEAItemId },
 	{ 0x06, 0x23, kTheSprite,			kTheMemberNum,		true, kTEAItemId }, // D5
-	{ 0x06, 0x24, kTheSprite, 			kTheCastLibNum, 	true, kTEAItemId },
-	{ 0x06, 0x25, kTheSprite,			kTheMember,			true, kTEAItemId },
+	{ 0x06, 0x24, kTheSprite, 			kTheCastLibNum, 	true, kTEAItemId }, // D5
+	{ 0x06, 0x25, kTheSprite,			kTheMember,			true, kTEAItemId }, // D5
+	// scriptInstanceList
+	// currentTime
+	// mostRecentCuePoint
+	// tweened
+	// name
 
 	{ 0x07, 0x01, kTheBeepOn,			kTheNOField,		true, kTEANOArgs },
 	{ 0x07, 0x02, kTheButtonStyle,		kTheNOField,		true, kTEANOArgs },
@@ -250,6 +255,11 @@ static const LingoV4TheEntity lingoV4TheEntity[] = {
 	{ 0x07, 0x21, kTheTimeoutPlay,		kTheNOField,		true, kTEANOArgs },
 	{ 0x07, 0x22, kTheTimer,			kTheNOField,		true, kTEANOArgs },
 	{ 0x07, 0x23, kThePreLoadRAM,		kTheNOField,		true, kTEANOArgs },
+	{ 0x07, 0x24, kTheVideoForWindowsPresent, kTheNOField,	true, kTEANOArgs }, // D5
+	// netPresent
+	// safePlayer
+	// soundKeepDevice
+	// soundMixMedia
 
 	{ 0x08, 0x01, kThePerFrameHook,		kTheNOField,		true, kTEANOArgs },
 	{ 0x08, 0x02, kTheCastMembers,		kTheNumber,			false, kTEANOArgs },
@@ -270,6 +280,7 @@ static const LingoV4TheEntity lingoV4TheEntity[] = {
 	{ 0x09, 0x0b, kTheCast,				kTheSize,			true, kTEAItemId },
 	{ 0x09, 0x11, kTheCast,				kTheForeColor,		true, kTEAItemId },
 	{ 0x09, 0x12, kTheCast,				kTheBackColor,		true, kTEAItemId },
+	{ 0x09, 0x13, kTheCast,				kTheType,			true, kTEAItemId }, // D5
 
 	// the chunk of cast
 	{ 0x0a, 0x03, kTheChunk,			kTheTextStyle,		true, kTEAChunk },
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8f1e31a9642..f13a5e3d0d6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -47,11 +47,13 @@ namespace Director {
 
 class Sprite;
 
-const TheEntity entities[] = {
-	{ kTheActorList,		"actorList",		false, 400, false },	//			D4 property
+TheEntity entities[] = {					//	hasId  ver.	isFunction
+	{ kTheActiveWindow,		"activeWindow",		false, 500, false },	//				D5 property
+	{ kTheActorList,		"actorList",		false, 400, false },	//			D4 p
 	{ kTheBeepOn,			"beepOn",			false, 200, false },	// D2 p
 	{ kTheButtonStyle,		"buttonStyle",		false, 200, false },	// D2 p
 	{ kTheCast,				"cast",				true,  200, false },	// D2
+	{ kTheCastLibs,			"castLibs",			false, 500, false },	//				D5 p
 	{ kTheCastMembers,		"castmembers",		false, 300, false },	//		 D3
 	{ kTheCenterStage,		"centerStage",		false, 200, false },	// D2 p
 	{ kTheCheckBoxAccess,	"checkBoxAccess",	false, 200, false },	// D2 p
@@ -64,8 +66,10 @@ const TheEntity entities[] = {
 	{ kTheCommandDown,		"commandDown",		false, 200, true },	// D2 f
 	{ kTheControlDown,		"controlDown",		false, 200, true },	// D2 f
 	{ kTheDate,				"date",				false, 300, true },	//		D3 f
-	{ kTheDeskTopRectList,	"deskTopRectList",	false, 500, true },	// D5 p
+	{ kTheDeskTopRectList,	"deskTopRectList",	false, 500, true },	//					D5 p
+	{ kTheDigitalVideoTimeScale,"digitalVideoTimeScale",false, 500, false },//			D5 p
 	{ kTheDoubleClick,		"doubleClick",		false, 200, true },	// D2 f
+	{ kTheEmulateMultiButtonMouse,"emulateMultiButtonMouse",false, 500, false },//		D5 p
 	{ kTheExitLock,			"exitLock",			false, 200, false },	// D2 p
 	{ kTheField,			"field",			true,  300, false },	//		D3
 	{ kTheFixStageSize,		"fixStageSize",		false, 200, false },	// D2 p
@@ -77,12 +81,17 @@ const TheEntity entities[] = {
 	{ kTheFrameTempo,		"frameTempo",		false, 400, true },	//			D4 f
 	{ kTheFreeBlock,		"freeBlock",		false, 200, true },	// D2 f
 	{ kTheFreeBytes,		"freeBytes",		false, 200, true },	// D2 f
+	{ kTheFrontWindow,		"frontWindow",		false, 500, false },//					D5 p
 	{ kTheFullColorPermit,	"fullColorPermit",	false, 200, false },	// D2 p
+	{ kTheIdleLoadMode,		"idleLoadMode",		false, 500, false },//					D5 p
+	{ kTheIdleLoadPeriod,	"idleLoadPeriod",	false, 500, false },//					D5 p
+	{ kTheIdleLoadTag,		"idleLoadTag",		false, 500, false },//					D5 p
 	{ kTheImageDirect,		"imageDirect",		false, 200, false },	// D2 p
 	{ kTheItemDelimiter,	"itemDelimiter",	false, 400, false },	//			D4 p
 	{ kTheKey,				"key",				false, 200, true },	// D2 f
 	{ kTheKeyCode,			"keyCode",			false, 200, true },	// D2 f
 	{ kTheKeyDownScript,	"keyDownScript",	false, 200, false },	// D2 p
+	{ kTheKeyPressed,		"keyPressed",		false, 500, false },//					D5 p
 	{ kTheKeyUpScript,		"keyUpScript",		false, 400, false },	//			D4 p
 	{ kTheLabelList,		"labelList",		false, 300, true },	//		D3 f
 	{ kTheLastClick,		"lastClick",		false, 200, true },	// D2 f
@@ -201,18 +210,29 @@ const TheEntityField fields[] = {
 	{ kTheSprite,	"visible",		kTheVisible,	400 },//				D4 p
 	{ kTheSprite,	"width",		kTheWidth,		200 },// D2 p
 
+	// Cast library fields
+	{ kTheCastLib,	"fileName",		kTheFileName,	500 },//					D5 p
+	{ kTheCastLib,	"name",			kTheName,		500 },//					D5 p
+	{ kTheCastLib,	"number",		kTheNumber,		500 },//					D5 p
+	{ kTheCastLib,	"preLoadMode",	kThePreLoadMode,500 },//					D5 p
+	{ kTheCastLib,	"selection",	kTheSelectionField,500 },//					D5 p
+
 	// Common cast fields
 	{ kTheCast,		"backColor",	kTheBackColor,	400 },//				D4 p
 	{ kTheCast,		"castLibNum",	kTheCastLibNum,	500 },// 					D5 p
 	{ kTheCast,		"castType",		kTheCastType,	400 },//				D4 p
 	{ kTheCast,		"filename",		kTheFileName,	400 },//				D4 p
+	{ kTheCast,		"editable",		kTheEditable,	500 },//					D5 p
 	{ kTheCast,		"foreColor",	kTheForeColor,	400 },//				D4 p
 	{ kTheCast,		"height",		kTheHeight,		400 },//				D4 p
+	{ kTheCast,		"idleReadChunkSize",kTheIdleReadChunkSize,500 },//			D5 p
 	{ kTheCast,		"loaded",		kTheLoaded,		400 },//				D4 p
-	{ kTheCast,		"modified",		kTheModified,	400 },//				D4 p
+	{ kTheCast,		"media",		kTheMedia,		500 },//					D5 p
 	{ kTheCast,		"memberNum",	kTheMemberNum,	500 },//					D5 p
+	{ kTheCast,		"modified",		kTheModified,	400 },//				D4 p
 	{ kTheCast,		"name",			kTheName,		300 },//		D3 p
 	{ kTheCast,		"number",		kTheNumber,		300 },//		D3 p
+	{ kTheCast,		"pageHeight",	kThePageHeight,	500 },//					D5 p
 	{ kTheCast,		"rect",			kTheRect,		400 },//				D4 p
 	{ kTheCast,		"purgePriority",kThePurgePriority,400 },//				D4 p // 0 Never purge, 1 Purge Last, 2 Purge next, 2 Purge normal
 	{ kTheCast,		"scriptText",	kTheScriptText,	400 },//				D4 p
@@ -224,6 +244,7 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"center",		kTheCenter,		400 },//				D4 p
 	{ kTheCast,		"controller",	kTheController,	300 },//		D3.1 p
 	{ kTheCast,		"crop",			kTheCrop,		400 },//				D4 p
+	{ kTheCast,		"digitalVideoType",kTheDigitalVideoType,500 },//			D5 p
 	{ kTheCast,		"directToStage",kTheDirectToStage,300 },//		D3.1 p
 	{ kTheCast,		"duration",		kTheDuration,	300 },//		D3.1 p
 	{ kTheCast,		"frameRate",	kTheFrameRate,	400 },//				D4 p
@@ -238,6 +259,10 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"video",		kTheVideo,		400 },//				D4 p
 	{ kTheSprite,	"volume",		kTheVolume,		300 },//		D3.1 p
 
+	// Movie fields
+	{ kTheCast,		"scriptsEnabled",	kTheScriptsEnabled,	500 },//			D5 p
+
+
 	// Bitmap fields
 	{ kTheCast,		"depth",		kTheDepth,		400 },//				D4 p
 	{ kTheCast,		"regPoint",		kTheRegPoint,	400 },//				D4 p
@@ -254,10 +279,26 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"textStyle",	kTheTextStyle,	300 },//		D3 p
 	{ kTheCast,		"scrollTop",	kTheScrollTop,  500 },//						D5 p
 
+	// ButtonCastMember fields
+	{ kTheCast,		"buttonType",	kTheButtonType,	500 },//						D5 p
+
+	// ShapeCastMember fields
+	{ kTheCast,		"filled",		kTheFilled,		500 },//						D5 p
+	{ kTheCast,		"lineSize",		kTheLineSize,	500 },//						D5 p
+
+	// TransitionCastMember fields
+	{ kTheCast,		"chunkSize",	kTheChunkSize,	500 },//						D5 p
+	{ kTheCast,		"transitionType",kTheTransitionType,500 },//					D5 p
 
 	// Field fields
+	{ kTheField,	"autoTab",		kTheAutoTab,	500 },//						D5 p
+	{ kTheField,	"border",		kTheBorder,		500 },//						D5 p
+	{ kTheField,	"boxType",		kTheBoxType,	500 },//						D5 p
+	{ kTheField,	"dropShadow",	kTheDropShadow,	500 },//						D5 p
 	{ kTheField,	"foreColor",	kTheForeColor,	400 },//				D4 p
 	{ kTheField,	"hilite",		kTheHilite,		200 },// D2 p
+	{ kTheField,	"lineCount",	kTheLineCount,	500 },//						D5 p
+	{ kTheField,	"margin",		kTheMargin,		500 },//						D5 p
 	{ kTheField,	"name",			kTheName,		300 },//		D3 p
 	{ kTheField,	"text",			kTheText,		200 },// D2 p
 	{ kTheField,	"textAlign",	kTheTextAlign,	300 },//		D3 p
@@ -294,6 +335,8 @@ const TheEntityField fields[] = {
 
 	{ kTheCastMembers,	"number",	kTheNumber,		300 },// 		D3 p
 
+	{ kTheCastLibs,		"number",	kTheNumber,		500 },//						D5 p
+
 	{ kTheDate,		"short",		kTheShort,		300 },//		D3 f
 	{ kTheDate,		"long",			kTheLong,		300 },//		D3 f
 	{ kTheDate,		"abbreviated",	kTheAbbr,		300 },//		D3 f
@@ -1273,9 +1316,14 @@ int Lingo::getCastLibsNum() {
 }
 
 int Lingo::getMembersNum() {
-	// FIXME: deal with D5 castlibs
 	Movie *movie = _vm->getCurrentMovie();
-	return (MAX(movie->getCast()->getCastMaxID(), (movie->_sharedCast ? movie->_sharedCast->getCastMaxID() : 0)));
+	int castLib = 0;
+	if (g_director->getVersion() >= 500) {
+		LB::b_castLib(1);
+		castLib = g_lingo->pop().u.i;
+	}
+	Cast *cast = movie->getCast(CastMemberID(0, castLib));
+	return (MAX(cast->getCastMaxID(), (movie->_sharedCast ? movie->_sharedCast->getCastMaxID() : 0)));
 }
 
 int Lingo::getXtrasNum() {
@@ -2002,8 +2050,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		g_lingo->push(d);
 		g_debugger->propReadHook(propName);
 		return;
-	}
-	if (obj.type == PARRAY) {
+	} else if (obj.type == PARRAY) {
 		int index = LC::compareArrays(LC::eqData, obj, propName, true).u.i;
 		if (index > 0) {
 			d = obj.u.parr->arr[index - 1].v;
@@ -2011,8 +2058,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		g_lingo->push(d);
 		g_debugger->propReadHook(propName);
 		return;
-	}
-	if (obj.type == POINT) {
+	} else if (obj.type == POINT) {
 		if (propName.equalsIgnoreCase("locH")) {
 			d = obj.u.farr->arr[0];
 		} else if (propName.equalsIgnoreCase("locV")) {
@@ -2023,8 +2069,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		g_lingo->push(d);
 		g_debugger->propReadHook(propName);
 		return;
-	}
-	if (obj.type == RECT) {
+	} else if (obj.type == RECT) {
 		if (propName.equalsIgnoreCase("left")) {
 			d = obj.u.farr->arr[0];
 		} else if (propName.equalsIgnoreCase("top")) {
@@ -2039,8 +2084,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		g_lingo->push(d);
 		g_debugger->propReadHook(propName);
 		return;
-	}
-	if (obj.type == CASTREF) {
+	} else if (obj.type == CASTREF) {
 		Movie *movie = _vm->getCurrentMovie();
 		if (!movie) {
 			g_lingo->lingoError("Lingo::getObjectProp(): No movie loaded");
@@ -2121,7 +2165,24 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		}
 		g_lingo->push(d);
 		return;
+	} else if (obj.type == CASTLIBREF) {
+		Movie *movie = _vm->getCurrentMovie();
+		if (!movie) {
+			g_lingo->lingoError("Lingo::getObjectProp(): No movie loaded");
+			g_lingo->push(d);
+			return;
+		}
+		Cast *cast = movie->getCast(CastMemberID(0, obj.u.i));
+		if (!cast) {
+			g_lingo->lingoError("Lingo::getObjectProp(): CastLib %d not found", obj.u.i);
+			g_lingo->push(d);
+			return;
+		}
+
+
+
 	}
+
 	if (_builtinFuncs.contains(propName) && _builtinFuncs[propName].nargs == 1) {
 		push(obj);
 		LC::call(_builtinFuncs[propName], 1, true);
@@ -2191,6 +2252,18 @@ void Lingo::setObjectProp(Datum &obj, Common::String &propName, Datum &val) {
 		} else {
 			g_lingo->lingoError("Lingo::setObjectProp(): %s has no property '%s'", id.asString().c_str(), propName.c_str());
 		}
+	} else if (obj.type == CASTLIBREF) {
+		Movie *movie = _vm->getCurrentMovie();
+		if (!movie) {
+			g_lingo->lingoError("Lingo::setObjectProp(): No movie loaded");
+			return;
+		}
+		Cast *cast = movie->getCast(CastMemberID(0, obj.u.i));
+		if (!cast) {
+			g_lingo->lingoError("Lingo::setObjectProp(): CastLib %d not found", obj.u.i);
+			return;
+		}
+
 	} else {
 		g_lingo->lingoError("Lingo::setObjectProp: Invalid object: %s", obj.asString(true).c_str());
 	}
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index 2db85743d98..ab7c0e94b6e 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -27,10 +27,12 @@ namespace Director {
 enum TheEntityType {
 	kTheNOEntity = 0,
 	kTheObject = 1,
-	kTheActorList = 2,
+	kTheActiveWindow,
+	kTheActorList,
 	kTheBeepOn,
 	kTheButtonStyle,
 	kTheCast,
+	kTheCastLib,
 	kTheCastLibs,
 	kTheCastMembers,
 	kTheCenterStage,
@@ -46,7 +48,9 @@ enum TheEntityType {
 	kTheControlDown,
 	kTheDate,
 	kTheDeskTopRectList,
+	kTheDigitalVideoTimeScale,
 	kTheDoubleClick,
+	kTheEmulateMultiButtonMouse,
 	kTheExitLock,
 	kTheField,
 	kTheFixStageSize,
@@ -58,13 +62,18 @@ enum TheEntityType {
 	kTheFrameTempo,
 	kTheFreeBlock,
 	kTheFreeBytes,
+	kTheFrontWindow,
 	kTheFullColorPermit,
+	kTheIdleLoadMode,
+	kTheIdleLoadPeriod,
+	kTheIdleLoadTag,
 	kTheImageDirect,
 	kTheItemDelimiter,
 	kTheItems,
 	kTheKey,
 	kTheKeyCode,
 	kTheKeyDownScript,
+	kTheKeyPressed,
 	kTheKeyUpScript,
 	kTheLabelList,
 	kTheLastClick,
@@ -157,33 +166,44 @@ enum TheEntityType {
 enum TheFieldType {
 	kTheNOField = 0,
 	kTheAbbr    = 1,
+	kTheAutoTab,
 	kTheBackColor,
 	kTheBlend,
+	kTheBorder,
 	kTheBottom,
+	kTheBoxType,
+	kTheButtonType,
 	kTheCastLibNum,
 	kTheCastNum,
 	kTheCastType,
 	kTheCenter,
 	kTheCheckMark,
+	kTheChunkSize,
 	kTheConstraint,
 	kTheController,
 	kTheCrop,
 	kTheCursor,
 	kTheDepth,
+	kTheDigitalVideoType,
 	kTheDirectToStage,
 	kTheDrawRect,
+	kTheDropShadow,
 	kTheDuration,
+	kTheEditable,
 	kTheEditableText,
 	kTheEnabled,
 	kTheFileName,
+	kTheFilled,
 	kTheForeColor,
 	kTheFrameRate,
 	kTheHeight,
 	kTheHilite,
 	kTheImmediate,
+	kTheIdleReadChunkSize,
 	kTheInk,
 	kTheLast,
 	kTheLeft,
+	kTheLineCount,
 	kTheLineSize,
 	kTheLoaded,
 	kTheLoc,
@@ -191,6 +211,8 @@ enum TheFieldType {
 	kTheLocV,
 	kTheLong,
 	kTheLoop,
+	kTheMargin,
+	kTheMedia,
 	kTheMember,
 	kTheMemberNum,
 	kTheModal,
@@ -200,11 +222,13 @@ enum TheFieldType {
 	kTheMovieTime,
 	kTheName,
 	kTheNumber,
+	kThePageHeight,
 	kThePalette,
 	kThePattern,
 	kThePausedAtStart,
 	kThePicture,
 	kThePreLoad,
+	kThePreLoadMode,
 	kThePuppet,
 	kThePurgePriority,
 	kTheRect,
@@ -214,6 +238,8 @@ enum TheFieldType {
 	kTheScript,
 	kTheScriptNum,
 	kTheScriptText,
+	kTheScriptsEnabled,
+	kTheSelectionField,
 	kTheShort,
 	kTheSize,
 	kTheSound,
@@ -232,6 +258,7 @@ enum TheFieldType {
 	kTheTitleVisible,
 	kTheTop,
 	kTheTrails,
+	kTheTransitionType,
 	kTheType,
 	kTheVideo,
 	kTheVisibility,
diff --git a/engines/director/stxt.cpp b/engines/director/stxt.cpp
index bdf57c9f005..c679e27ea79 100644
--- a/engines/director/stxt.cpp
+++ b/engines/director/stxt.cpp
@@ -32,7 +32,7 @@ Stxt::Stxt(Cast *cast, Common::SeekableReadStreamEndian &textStream) : _cast(cas
 
 	_textType = kTextTypeFixed;
 	_textAlign = kTextAlignLeft;
-	_textShadow = kSizeNone;
+	_textShadow = 0;
 	_unk1f = _unk2f = 0;
 	_unk3f = 0;
 	_size = textStream.size();
diff --git a/engines/director/stxt.h b/engines/director/stxt.h
index f1ae680ee14..27ee69d5977 100644
--- a/engines/director/stxt.h
+++ b/engines/director/stxt.h
@@ -57,7 +57,7 @@ public:
 	Common::String _rtext;
 	TextType _textType;
 	TextAlignType _textAlign;
-	SizeType _textShadow;
+	uint8 _textShadow;
 
 	uint32 _size;
 
diff --git a/engines/director/types.h b/engines/director/types.h
index 5782d42da56..bf995ccff2e 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -135,15 +135,6 @@ enum TextFlag {
 	kTextFlagDoNotWrap	= (1 << 2)
 };
 
-enum SizeType {
-	kSizeNone,
-	kSizeSmallest,
-	kSizeSmall,
-	kSizeMedium,
-	kSizeLarge,
-	kSizeLargest
-};
-
 enum ButtonType {
 	kTypeButton,
 	kTypeCheckBox,


Commit: 43b63504c7aaafd14c00141147994f113bf0440f
    https://github.com/scummvm/scummvm/commit/43b63504c7aaafd14c00141147994f113bf0440f
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Update detection entry for ukiuki1

Changed paths:
  A engines/director/lingo/xlibs/tengu.cpp
  A engines/director/lingo/xlibs/tengu.h
    engines/director/detection_tables.h
    engines/director/lingo/lingo-object.cpp
    engines/director/module.mk


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 356893c2884..0288df0445e 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -5959,9 +5959,10 @@ static const DirectorGameDescription gameDescriptions[] = {
 	WINGAME1("ubt", "", "BTDEMO.EXE", "dbe72b7dc91c72db5b4597857aecf5c6", 696813, 404),
 
 	// YOBI.EXE is a projector for lower performance systems
-	WINGAME1_l("ukiuki1", "",	  "TENNGU.EXE", "f0bbb9938a7cb899b6fc93ef7f3e8150", 747145, Common::JA_JPN, 404),
+	WINGAME1_l("ukiuki1", "",	  "TENNGU.EXE", "t:2bfc6908e01ec3e743189daa7578d30a", 747145, Common::JA_JPN, 404),
 	WINDEMO2_l("ukiuki1", "Demo", "S.EXE",		"09430e02b3540e623d0b400792958901", 747145,
 								  "LOGO.DIR",	"b6d341c63fbea25898fc310981413c28", 1053528, Common::JA_JPN, 404),
+	MACGAME1_l("ukiuki1", "",     "xn--u9j393jyrduwqoth", "r:bcd3c718db258701496b3c5bcb827ef2", 488662, Common::JA_JPN, 404),
 	WINGAME1("ukiukibgv", "",	  "BGV",		"4dc07ac998272bb4027a9979f5b6c3b6", 1097649, 404),
 	{
 		{
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 793fd8c0c0b..63998cf2c4f 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -118,6 +118,7 @@
 #include "director/lingo/xlibs/spacemgr.h"
 #include "director/lingo/xlibs/stagetc.h"
 #include "director/lingo/xlibs/syscolor.h"
+#include "director/lingo/xlibs/tengu.h"
 #include "director/lingo/xlibs/unittest.h"
 #include "director/lingo/xlibs/valkyrie.h"
 #include "director/lingo/xlibs/videodiscxobj.h"
@@ -304,6 +305,7 @@ static const struct XLibProto {
 	XLIBDEF(SpaceMgr,			kXObj,			400),	// D4
 	XLIBDEF(StageTCXObj,		kXObj,			400),	// D4
 	XLIBDEF(SysColorXObj,			kXObj,					400),	// D4
+	XLIBDEF(TenguXObj,			kXObj,					400),	// D4
 	XLIBDEF(TimextraXtra,		kXtraObj,		500),	// D5
 	XLIBDEF(UnitTestXObj,		kXObj,			400),	// D4
 	XLIBDEF(VMisOnXFCN,			kXObj,			400),	// D4
diff --git a/engines/director/lingo/xlibs/tengu.cpp b/engines/director/lingo/xlibs/tengu.cpp
new file mode 100644
index 00000000000..fff2b52935e
--- /dev/null
+++ b/engines/director/lingo/xlibs/tengu.cpp
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/tengu.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * [insert game here]
+ *
+ **************************************************/
+
+/*
+--Tengu External Factory. 1996
+--Tengu
+I                  mNew                        --Creates a new inctance of XObject
+X                      mDispose                --Dispose of XObject instance
+IIIIS          mSetMenu                --Setting Menu Movie Variable
+IIII           mGameStart              --Setting Game Start Variable
+IIS            mSetArea                --Setting Area Data
+XIIII          mSetShikake             --Setting Shikake Data
+XIII           mSetEsa                 --Setting Esa Data
+III            mGetTime                --Getting Now Time
+II                     mGetPal                 --Getting Pallete Data
+II                     mGetAtari               --Getting Atari Data
+XI                     mSetNode                --Setting Node Data
+III            mGetUkiLoc              --Getting Uki Location Data
+I                      mGetUkiTime             --Getting Uki Shinking and Floating Time
+II                     mGetSaoDepth    --Getting Water Depth in Now Sao
+XI                     mContinue               --Setting Data in Game Continueing
+IIII           mGetValue               --Getting A Set Of Values
+I                      mGetFuna                --Getting Funa Data
+II                     mWriteData              --Writting Binary Data
+II                     mReadData               --Reading Binary Data
+IIS            mAlert                  --Setting Alert Mode
+XII            mSetScore               --Setting Score Data
+XII            mSetChoka               --Setting Choka Data
+ISS            mGyotaku                --Writting Gyotaku data
+II                     mESearch                --Searching Event Data
+XIII           mTournament             --Setting Tournament Data
+X                      mSetYudachi             --Setting Shower Mode
+IIS            mSetEvent               --Setting Event Data
+ */
+
+namespace Director {
+
+const char *TenguXObj::xlibName = "Tengu";
+const XlibFileDesc TenguXObj::fileNames[] = {
+	{ "TENGU",   nullptr },
+	{ nullptr,        nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+	{ "new",				TenguXObj::m_new,		 0, 0,	400 },
+	{ "dispose",				TenguXObj::m_dispose,		 0, 0,	400 },
+	{ "setMenu",				TenguXObj::m_setMenu,		 4, 4,	400 },
+	{ "gameStart",				TenguXObj::m_gameStart,		 3, 3,	400 },
+	{ "setArea",				TenguXObj::m_setArea,		 2, 2,	400 },
+	{ "setShikake",				TenguXObj::m_setShikake,		 4, 4,	400 },
+	{ "setEsa",				TenguXObj::m_setEsa,		 3, 3,	400 },
+	{ "getTime",				TenguXObj::m_getTime,		 2, 2,	400 },
+	{ "getPal",				TenguXObj::m_getPal,		 1, 1,	400 },
+	{ "getAtari",				TenguXObj::m_getAtari,		 1, 1,	400 },
+	{ "setNode",				TenguXObj::m_setNode,		 1, 1,	400 },
+	{ "getUkiLoc",				TenguXObj::m_getUkiLoc,		 2, 2,	400 },
+	{ "getUkiTime",				TenguXObj::m_getUkiTime,		 0, 0,	400 },
+	{ "getSaoDepth",				TenguXObj::m_getSaoDepth,		 1, 1,	400 },
+	{ "continue",				TenguXObj::m_continue,		 1, 1,	400 },
+	{ "getValue",				TenguXObj::m_getValue,		 3, 3,	400 },
+	{ "getFuna",				TenguXObj::m_getFuna,		 0, 0,	400 },
+	{ "writeData",				TenguXObj::m_writeData,		 1, 1,	400 },
+	{ "readData",				TenguXObj::m_readData,		 1, 1,	400 },
+	{ "alert",				TenguXObj::m_alert,		 2, 2,	400 },
+	{ "setScore",				TenguXObj::m_setScore,		 2, 2,	400 },
+	{ "setChoka",				TenguXObj::m_setChoka,		 2, 2,	400 },
+	{ "gyotaku",				TenguXObj::m_gyotaku,		 2, 2,	400 },
+	{ "eSearch",				TenguXObj::m_eSearch,		 1, 1,	400 },
+	{ "tournament",				TenguXObj::m_tournament,		 3, 3,	400 },
+	{ "setYudachi",				TenguXObj::m_setYudachi,		 0, 0,	400 },
+	{ "setEvent",				TenguXObj::m_setEvent,		 2, 2,	400 },
+	{ nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+TenguXObject::TenguXObject(ObjectType ObjectType) :Object<TenguXObject>("Tengu") {
+	_objType = ObjectType;
+}
+
+void TenguXObj::open(ObjectType type, const Common::Path &path) {
+    TenguXObject::initMethods(xlibMethods);
+    TenguXObject *xobj = new TenguXObject(type);
+    if (type == kXtraObj)
+        g_lingo->_openXtras.push_back(xlibName);
+    g_lingo->exposeXObject(xlibName, xobj);
+    g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void TenguXObj::close(ObjectType type) {
+    TenguXObject::cleanupMethods();
+    g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void TenguXObj::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("TenguXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUBNR(TenguXObj::m_dispose)
+XOBJSTUB(TenguXObj::m_setMenu, 0)
+XOBJSTUB(TenguXObj::m_gameStart, 0)
+XOBJSTUB(TenguXObj::m_setArea, 0)
+XOBJSTUBNR(TenguXObj::m_setShikake)
+XOBJSTUBNR(TenguXObj::m_setEsa)
+XOBJSTUB(TenguXObj::m_getTime, 10)
+XOBJSTUB(TenguXObj::m_getPal, 0)
+XOBJSTUB(TenguXObj::m_getAtari, 0)
+XOBJSTUBNR(TenguXObj::m_setNode)
+XOBJSTUB(TenguXObj::m_getUkiLoc, 0)
+XOBJSTUB(TenguXObj::m_getUkiTime, 0)
+XOBJSTUB(TenguXObj::m_getSaoDepth, 0)
+XOBJSTUBNR(TenguXObj::m_continue)
+XOBJSTUB(TenguXObj::m_getValue, 0)
+XOBJSTUB(TenguXObj::m_getFuna, 0)
+XOBJSTUB(TenguXObj::m_writeData, 0)
+XOBJSTUB(TenguXObj::m_readData, 0)
+XOBJSTUB(TenguXObj::m_alert, 0)
+XOBJSTUBNR(TenguXObj::m_setScore)
+XOBJSTUBNR(TenguXObj::m_setChoka)
+XOBJSTUB(TenguXObj::m_gyotaku, 0)
+XOBJSTUB(TenguXObj::m_eSearch, 0)
+XOBJSTUBNR(TenguXObj::m_tournament)
+XOBJSTUBNR(TenguXObj::m_setYudachi)
+XOBJSTUB(TenguXObj::m_setEvent, 0)
+
+}
diff --git a/engines/director/lingo/xlibs/tengu.h b/engines/director/lingo/xlibs/tengu.h
new file mode 100644
index 00000000000..9059837be10
--- /dev/null
+++ b/engines/director/lingo/xlibs/tengu.h
@@ -0,0 +1,72 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XLIBS_TENGU_H
+#define DIRECTOR_LINGO_XLIBS_TENGU_H
+
+namespace Director {
+
+class TenguXObject : public Object<TenguXObject> {
+public:
+	TenguXObject(ObjectType objType);
+};
+
+namespace TenguXObj {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_dispose(int nargs);
+void m_setMenu(int nargs);
+void m_gameStart(int nargs);
+void m_setArea(int nargs);
+void m_setShikake(int nargs);
+void m_setEsa(int nargs);
+void m_getTime(int nargs);
+void m_getPal(int nargs);
+void m_getAtari(int nargs);
+void m_setNode(int nargs);
+void m_getUkiLoc(int nargs);
+void m_getUkiTime(int nargs);
+void m_getSaoDepth(int nargs);
+void m_continue(int nargs);
+void m_getValue(int nargs);
+void m_getFuna(int nargs);
+void m_writeData(int nargs);
+void m_readData(int nargs);
+void m_alert(int nargs);
+void m_setScore(int nargs);
+void m_setChoka(int nargs);
+void m_gyotaku(int nargs);
+void m_eSearch(int nargs);
+void m_tournament(int nargs);
+void m_setYudachi(int nargs);
+void m_setEvent(int nargs);
+
+} // End of namespace TenguXObj
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index 35f1e9c71f2..acf3950056e 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -147,6 +147,7 @@ MODULE_OBJS = \
 	lingo/xlibs/spacemgr.o \
 	lingo/xlibs/stagetc.o \
 	lingo/xlibs/syscolor.o \
+	lingo/xlibs/tengu.o \
 	lingo/xlibs/unittest.o \
 	lingo/xlibs/valkyrie.o \
 	lingo/xlibs/videodiscxobj.o \


Commit: 007c3e687bbe1795490c2bc7074a7fe3137ebc39
    https://github.com/scummvm/scummvm/commit/007c3e687bbe1795490c2bc7074a7fe3137ebc39
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Track timeout figures as signed integer

Previously, using unsigned integers made it possible to overflow the
timeout check, as you can redefine the tick baseline (and therefore
the last timeout figure) via Lingo.

Fixes catching mice in The Great Green Mouse Disaster.

Changed paths:
    engines/director/director.h
    engines/director/events.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/movie.h
    engines/director/types.h


diff --git a/engines/director/director.h b/engines/director/director.h
index 6a80c22d237..4f7e47e3066 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -238,7 +238,7 @@ public:
 	bool pollEvent(Common::Event &event);
 	bool processEvents(bool captureClick = false, bool skipWindowManager = false);
 	void processEventQUIT();
-	uint32 getMacTicks();
+	int getMacTicks();
 	Common::Array<Common::Event> _injectedEvents;
 
 	// game-quirks.cpp
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index cb8ba0d6f64..07378b392fc 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -38,7 +38,7 @@
 
 namespace Director {
 
-uint32 DirectorEngine::getMacTicks() { return (g_system->getMillis() * 60 / 1000.) - _tickBaseline; }
+int DirectorEngine::getMacTicks() { return (int)(g_system->getMillis() * 60 / 1000.) - _tickBaseline; }
 
 bool DirectorEngine::pollEvent(Common::Event &event) {
 	// used by UnitTest XObject
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index f13a5e3d0d6..27c9ab2f468 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1237,7 +1237,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 	case kTheTimeoutLapsed:
 		// timeOutLapsed can be set in D4, but can't in D3. see D3.1 interactivity manual p312 and D4 dictionary p296.
 		if (g_director->getVersion() >= 400 && (d.type == INT || d.type == FLOAT)) {
-			g_director->_tickBaseline = g_director->getMacTicks() - d.asInt();
+			g_director->_tickBaseline = (int)g_director->getMacTicks() - d.asInt();
 		}
 		if (d.type != INT) {
 			warning("Lingo::setTheEntity() : Wrong DatumType %d for setting of Lingo Property timeOutLapsed", d.type);
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 4fa3c688ec2..b78a431b4bd 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -182,8 +182,8 @@ public:
 
 	uint16 _currentHiliteChannelId;
 
-	uint _lastTimeOut;
-	uint _timeOutLength;
+	int _lastTimeOut;
+	int _timeOutLength;
 	bool _timeOutKeyDown;
 	bool _timeOutMouse;
 	bool _timeOutPlay;
diff --git a/engines/director/types.h b/engines/director/types.h
index bf995ccff2e..6d649b3d159 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -192,17 +192,18 @@ enum InkType {
 	kInkTypeDark
 };
 
+// ID matches up to the fake cast member ID used by EventScript
 enum LEvent {
-	kEventPrepareMovie,
+	kEventPrepareMovie, // 0
 	kEventStartMovie,
 	kEventStepMovie,
 	kEventStopMovie,
 
-	kEventNew,
+	kEventNew, // 4
 	kEventBeginSprite,
 	kEventEndSprite,
 
-	kEventNone,
+	kEventNone, // 7
 	kEventGeneric,
 	kEventEnterFrame,
 	kEventPrepareFrame,
@@ -211,14 +212,14 @@ enum LEvent {
 	kEventExitFrame,
 	kEventTimeout,
 
-	kEventActivateWindow,
+	kEventActivateWindow, // 15
 	kEventDeactivateWindow,
 	kEventMoveWindow,
 	kEventResizeWindow,
 	kEventOpenWindow,
 	kEventCloseWindow,
 
-	kEventKeyUp,
+	kEventKeyUp, // 21
 	kEventKeyDown,
 	kEventMouseUp,
 	kEventMouseDown,
@@ -229,9 +230,9 @@ enum LEvent {
 	kEventMouseUpOutSide,
 	kEventMouseWithin,
 
-	kEventStartUp,
+	kEventStartUp, // 31
 
-	kEventMenuCallback
+	kEventMenuCallback // 32
 };
 
 enum TransitionType {


Commit: 39c252e9935368751d32b11d2075bc26e119f5a1
    https://github.com/scummvm/scummvm/commit/39c252e9935368751d32b11d2075bc26e119f5a1
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Fix multiplexed cast member ID handling

In D5, the castNum will return a multiplexed ID instead of just the
member ID, and various other features will accept and use the
multiplexed ID.

Fixes the story playback and basic navigation in Smarty.

Changed paths:
    engines/director/cast.cpp
    engines/director/castmember/bitmap.cpp
    engines/director/castmember/castmember.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/types.h


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 7727fdad077..5d7c0359f53 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -720,7 +720,8 @@ void Cast::loadCast() {
 	// For D4+ we may request to force Lingo scripts and skip precompiled bytecode
 	if (_version >= kFileVer400 && !debugChannelSet(-1, kDebugNoBytecode)) {
 		// Try to load script context
-		if ((r = _castArchive->getFirstResource(MKTAG('L', 'c', 't', 'x'), _libResourceId)) != nullptr) {
+		// Even for multiple casts, ID is 1024
+		if ((r = _castArchive->getFirstResource(MKTAG('L', 'c', 't', 'x'), 1024)) != nullptr) {
 			loadLingoContext(*r);
 			delete r;
 		}
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 28df2c9d7db..5d927b86aaf 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -779,7 +779,7 @@ Datum BitmapCastMember::getField(int field) {
 	case kThePalette:
 		// D5 and below return an integer for this field
 		if (_clut.castLib > 0) {
-			d = Datum(_clut.member + 0x20000 * (_clut.castLib - 1));
+			d = Datum(_clut.toMultiplex());
 		} else {
 			d = Datum(_clut.member);
 		}
@@ -822,7 +822,7 @@ bool BitmapCastMember::setField(int field, const Datum &d) {
 				if (id > 0) {
 					// For palette IDs, D5 and above use multiples of 0x20000 to denote
 					// the castLib in the integer representation
-					newClut = CastMemberID(id % 0x20000, 1 + (id / 0x20000));
+					newClut = CastMemberID().fromMultiplex(id);
 				} else if (id < 0) {
 					// Negative integer refers to one of the builtin palettes
 					newClut = CastMemberID(id, -1);
diff --git a/engines/director/castmember/castmember.cpp b/engines/director/castmember/castmember.cpp
index 8096920a17b..539698ff673 100644
--- a/engines/director/castmember/castmember.cpp
+++ b/engines/director/castmember/castmember.cpp
@@ -176,9 +176,15 @@ Datum CastMember::getField(int field) {
 			d = Datum(castInfo->name);
 		break;
 	case kTheMemberNum:
-	case kTheNumber:
 		d = _castId;
 		break;
+	case kTheNumber:
+		if (g_director->getVersion() >= 500) {
+			d = CastMemberID(_castId, _cast->_castLibID).toMultiplex();
+		} else {
+			d = _castId;
+		}
+		break;
 	case kTheRect:
 		// not sure get the initial rect would be fine to castmember
 		d = Datum(_cast->getCastMember(_castId)->_initialRect);
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 27c9ab2f468..a0d2ac4a55f 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -451,7 +451,14 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		d = getCastLibsNum();
 		break;
 	case kTheCastMembers:
-		d = getMembersNum();
+		{
+			uint16 castLibID = 0;
+			if (g_director->getVersion() >= 500) {
+				LB::b_castLib(1);
+				castLibID = (uint16)g_lingo->pop().u.i;
+			}
+			d = getMembersNum(castLibID);
+		}
 		break;
 	case kTheCenterStage:
 		d = g_director->_centerStage;
@@ -1315,15 +1322,13 @@ int Lingo::getCastLibsNum() {
 	return _vm->getCurrentMovie()->getCasts()->size();
 }
 
-int Lingo::getMembersNum() {
+int Lingo::getMembersNum(uint16 castLibID) {
 	Movie *movie = _vm->getCurrentMovie();
-	int castLib = 0;
-	if (g_director->getVersion() >= 500) {
-		LB::b_castLib(1);
-		castLib = g_lingo->pop().u.i;
+	Cast *cast = movie->getCast(CastMemberID(0, castLibID));
+	if (cast) {
+		return MAX(cast->getCastMaxID(), (movie->_sharedCast ? movie->_sharedCast->getCastMaxID() : 0));
 	}
-	Cast *cast = movie->getCast(CastMemberID(0, castLib));
-	return (MAX(cast->getCastMaxID(), (movie->_sharedCast ? movie->_sharedCast->getCastMaxID() : 0)));
+	return 0;
 }
 
 int Lingo::getXtrasNum() {
@@ -1392,6 +1397,14 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
 		d = sprite->_castId;
 		break;
 	case kTheCastNum:
+		if (g_director->getVersion() >= 500) {
+			// For the castNum, D5 will multiplex the castLib ID into the result.
+			// the memberNum will just give you the member ID.
+			d = sprite->_castId.toMultiplex();
+		} else {
+			d = sprite->_castId.member;
+		}
+		break;
 	case kTheMemberNum:
 		d = sprite->_castId.member;
 		break;
@@ -1581,9 +1594,11 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 	case kTheMemberNum:
 		{
 			CastMemberID castId = d.asMemberID();
-			// Setting the cast ID as a number will preserve whatever is in castLib
-			if (d.isNumeric() && (sprite->_castId.castLib != 0)) {
-				castId = CastMemberID(d.asInt(), sprite->_castId.castLib);
+			if (g_director->getVersion() < 500 || field == kTheMemberNum) {
+				// Setting the cast ID as a number will preserve whatever is in castLib
+				if (d.isNumeric() && (sprite->_castId.castLib != 0)) {
+					castId = CastMemberID(d.asInt(), sprite->_castId.castLib);
+				}
 			}
 			CastMember *castMember = movie->getCastMember(castId);
 
@@ -1839,7 +1854,7 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 			d = 0;
 		} else if (field == kTheNumber) {
 			d = -1;
-		} else if (id.member <= getMembersNum()) {
+		} else if (id.member <= getMembersNum(id.castLib)) {
 			// If a cast member with the ID doesn't exist,
 			// but the ID isn't greater than the biggest cast member ID,
 			// Lingo will not crash, and instead return a VOID.
@@ -2136,7 +2151,11 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 					d = Datum(Common::Point(0, 0));
 					break;
 				case kTheNumber:
-					d = Datum(id.member);
+					if (g_director->getVersion() >= 500) {
+						d = Datum(id.toMultiplex());
+					} else {
+						d = Datum(id.member);
+					}
 					break;
 				default:
 					emptyAllowed = false;
@@ -2144,7 +2163,7 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 				}
 			}
 
-			if (id.member <= getMembersNum()) {
+			if (id.member <= getMembersNum(id.castLib)) {
 				// Cast member ID is within range (i.e. less than max)
 				// In real Director, accessing -any- of the properties will
 				// be allowed, but return garbage.
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 9f25f147800..c77ff4d68a0 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1896,6 +1896,10 @@ CastMemberID Lingo::resolveCastMember(const Datum &memberID, const Datum &castLi
 		break;
 	case INT:
 	case FLOAT:
+		if (g_director->getVersion() >= 500 && memberID.asInt() > 0x20000) {
+			// Composite ID
+			return CastMemberID().fromMultiplex(memberID.asInt());
+		}
 		if (castLib.asInt() == 0) {
 			// When specifying 0 as the castlib, D5 will assume this
 			// means the default (i.e. first) cast library. It will not
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 9b00c66a7a9..f9c7b044e92 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -359,7 +359,7 @@ public:
 	int getMenuItemsNum(Datum &d);
 	int getXtrasNum();
 	int getCastLibsNum();
-	int getMembersNum();
+	int getMembersNum(uint16 castLibID);
 
 	void executeHandler(const Common::String &name);
 	void executeScript(ScriptType type, CastMemberID id);
diff --git a/engines/director/types.h b/engines/director/types.h
index 6d649b3d159..475481fe5d2 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -423,6 +423,14 @@ struct CastMemberID {
 	Common::String asString() const;
 
 	uint hash() const { return ((castLib & 0xffff) << 16) + (member & 0xffff); }
+
+	CastMemberID fromMultiplex(int multiplexID) {
+		return CastMemberID(multiplexID % 0x20000, 1 + (multiplexID / 0x20000));
+	}
+
+	int toMultiplex() {
+		return member + 0x20000 * (castLib - 1);
+	}
 };
 
 enum CompareResult {


Commit: 753ea882c50208cbbf50c334811eea8b1823ef8e
    https://github.com/scummvm/scummvm/commit/753ea882c50208cbbf50c334811eea8b1823ef8e
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add entities/fields new to Director 5

Changed paths:
    engines/director/castmember/digitalvideo.cpp
    engines/director/castmember/digitalvideo.h
    engines/director/castmember/text.cpp
    engines/director/castmember/transition.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h
    engines/director/types.h


diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index 5b50764de94..55b72fca55f 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -52,6 +52,7 @@ DigitalVideoCastMember::DigitalVideoCastMember(Cast *cast, uint16 castId, Common
 	_frameRate = (_vflags >> 24) & 0xff;
 
 	_frameRateType = kFrameRateDefault;
+	_videoType = kDVUnknown;
 	if (_vflags & 0x0800) {
 		_frameRateType = (FrameRateType)((_vflags & 0x3000) >> 12);
 	}
@@ -106,6 +107,7 @@ DigitalVideoCastMember::DigitalVideoCastMember(Cast *cast, uint16 castId, Digita
 	_qtmovie = source._qtmovie;
 	_dirty = source._dirty;
 	_frameRateType = source._frameRateType;
+	_videoType = source._videoType;
 
 	_frameRate = source._frameRate;
 	_getFirstFrame = source._getFirstFrame;
@@ -160,7 +162,11 @@ bool DigitalVideoCastMember::loadVideo(Common::String path) {
 		    warning("DigitalVideoCastMember::loadVideo(): format not supported, skipping");
 		    delete _video;
 		    _video = nullptr;
+		} else {
+			_videoType = kDVVideoForWindows;
 		}
+	} else {
+		_videoType = kDVQuickTime;
 	}
 
 	if (result && g_director->_pixelformat.bytesPerPixel == 1) {
@@ -420,6 +426,7 @@ bool DigitalVideoCastMember::hasField(int field) {
 	case kTheCenter:
 	case kTheController:
 	case kTheCrop:
+	case kTheDigitalVideoType:
 	case kTheDirectToStage:
 	case kTheDuration:
 	case kTheFrameRate:
@@ -451,6 +458,15 @@ Datum DigitalVideoCastMember::getField(int field) {
 	case kTheCrop:
 		d = _crop;
 		break;
+	case kTheDigitalVideoType:
+		if (_videoType == kDVVideoForWindows) {
+			d = Datum("videoForWindows");
+		} else {
+			// for unknown, just pretend QuickTime
+			d = Datum("quickTime");
+		}
+		d.type = SYMBOL;
+		break;
 	case kTheDirectToStage:
 		d = _directToStage;
 		break;
@@ -495,6 +511,9 @@ bool DigitalVideoCastMember::setField(int field, const Datum &d) {
 	case kTheCrop:
 		_crop = (bool)d.asInt();
 		return true;
+	case kTheDigitalVideoType:
+		warning("DigitalVideoCastMember::setField(): Attempt to set read-only field %s of cast %d", g_lingo->entity2str(field), _castId);
+		return false;
 	case kTheDirectToStage:
 		_directToStage = (bool)d.asInt();
 		return true;
diff --git a/engines/director/castmember/digitalvideo.h b/engines/director/castmember/digitalvideo.h
index 2eccf7de934..64651b3b46d 100644
--- a/engines/director/castmember/digitalvideo.h
+++ b/engines/director/castmember/digitalvideo.h
@@ -30,6 +30,12 @@ class VideoDecoder;
 
 namespace Director {
 
+enum DigitalVideoType {
+	kDVQuickTime,
+	kDVVideoForWindows,
+	kDVUnknown = -1,
+};
+
 class DigitalVideoCastMember : public CastMember {
 public:
 	DigitalVideoCastMember(Cast *cast, uint16 castId, Common::SeekableReadStreamEndian &stream, uint16 version);
@@ -78,6 +84,7 @@ public:
 	bool _avimovie, _qtmovie;
 	bool _dirty;
 	FrameRateType _frameRateType;
+	DigitalVideoType _videoType;
 
 	uint16 _frameRate;
 	bool _getFirstFrame;
diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index 87e9720536c..ffe447705a6 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -481,6 +481,7 @@ bool TextCastMember::hasField(int field) {
 		return true;
 	case kTheBorder:
 	case kTheScrollTop:
+	case kTheWordWrap:
 		return _type == kCastText;
 	case kTheButtonType:
 		return _type == kCastButton;
@@ -553,6 +554,8 @@ Datum TextCastMember::getField(int field) {
 			break;
 		}
 		break;
+	case kTheWordWrap:
+		return _type == kCastText;
 	default:
 		d = CastMember::getField(field);
 	}
diff --git a/engines/director/castmember/transition.cpp b/engines/director/castmember/transition.cpp
index 070dab5f24c..3338350b313 100644
--- a/engines/director/castmember/transition.cpp
+++ b/engines/director/castmember/transition.cpp
@@ -46,7 +46,7 @@ TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, Common::Se
 		_flags = stream.readByte();
 		_area = !(_flags & 1);
 		_durationMillis = stream.readUint16BE();
-		debugC(5, kDebugLoading, "TransitionCastMember::TransitionCastMember(): transType: %d, durationMillis: %d, flags: %d, chunkSize: %d", _transType, _durationMillis, _flags, _chunkSize);
+		debugC(5, kDebugLoading, "TransitionCastMember::TransitionCastMember(): transType: %d, durationMillis: %d, flags: %d, chunkSize: %d, area: %d", _transType, _durationMillis, _flags, _chunkSize, _area);
 	} else {
 		warning("STUB: TransitionCastMember::TransitionCastMember(): Transitions not yet supported for version %d", _cast->_version);
 	}
@@ -65,6 +65,7 @@ TransitionCastMember::TransitionCastMember(Cast *cast, uint16 castId, Transition
 
 bool TransitionCastMember::hasField(int field) {
 	switch (field) {
+	case kTheChangeArea:
 	case kTheChunkSize:
 	case kTheDuration:
 	case kTheTransitionType:
@@ -79,6 +80,9 @@ Datum TransitionCastMember::getField(int field) {
 	Datum d;
 
 	switch (field) {
+	case kTheChangeArea:
+		d = Datum((int)_area);
+		break;
 	case kTheChunkSize:
 		d = Datum(_chunkSize);
 		break;
@@ -98,11 +102,14 @@ Datum TransitionCastMember::getField(int field) {
 
 bool TransitionCastMember::setField(int field, const Datum &d) {
 	switch (field) {
+	case kTheChangeArea:
+		_area = (bool)d.asInt();
+		break;
 	case kTheChunkSize:
 		_chunkSize = d.asInt();
 		return true;
 	case kTheDuration:
-		_durationMillis = (bool)d.asInt();
+		_durationMillis = d.asInt();
 		return true;
 	case kTheTransitionType:
 		_transType = (TransitionType)d.asInt();
@@ -115,7 +122,7 @@ bool TransitionCastMember::setField(int field, const Datum &d) {
 }
 
 Common::String TransitionCastMember::formatInfo() {
-	return Common::String::format("transType: %d, durationMillis: %d, flags: %d, chunkSize: %d", _transType, _durationMillis, _flags, _chunkSize);
+	return Common::String::format("transType: %d, durationMillis: %d, flags: %d, chunkSize: %d, area: %d", _transType, _durationMillis, _flags, _chunkSize, _area);
 }
 
 } // End of namespace Director
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index a0d2ac4a55f..51da8e1cfe9 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -76,9 +76,12 @@ TheEntity entities[] = {					//	hasId  ver.	isFunction
 	{ kTheFloatPrecision,	"floatPrecision",	false, 300, false },	//		D3 p
 	{ kTheFrame,			"frame",			false, 200, true },	// D2 f
 	{ kTheFrameLabel,		"frameLabel",		false, 400, false },	//			D4 p
-	{ kTheFrameScript,		"frameScript",		false, 400, false },	//			D4 p
 	{ kTheFramePalette,		"framePalette",		false, 400, false },	//			D4 p
-	{ kTheFrameTempo,		"frameTempo",		false, 400, true },	//			D4 f
+	{ kTheFrameScript,		"frameScript",		false, 400, false },	//			D4 p
+	{ kTheFrameSound1,		"frameSound1",		false, 500, false },	//				D5 p
+	{ kTheFrameSound2,		"frameSound2",		false, 500, false },	//				D5 p
+	{ kTheFrameTempo,		"frameTempo",		false, 400, false },	//			D4 p
+	{ kTheFrameTransition,	"frameTransition",	false, 500, false },	//				D5 p
 	{ kTheFreeBlock,		"freeBlock",		false, 200, true },	// D2 f
 	{ kTheFreeBytes,		"freeBytes",		false, 200, true },	// D2 f
 	{ kTheFrontWindow,		"frontWindow",		false, 500, false },//					D5 p
@@ -129,6 +132,7 @@ TheEntity entities[] = {					//	hasId  ver.	isFunction
 	{ kThePerFrameHook,		"perFrameHook",		false, 200, false },	// D2 p
 	{ kThePreloadEventAbort,"preloadEventAbort",false, 400, false },	//			D4 p
 	{ kThePreLoadRAM,		"preLoadRAM",		false, 400, false },	//			D4 p
+	{ kThePlatform,			"platform",			false, 500, false },	//				D5 p
 	{ kThePi,				"pi",				false, 400, true },	//			D4 f
 	{ kTheQuickTimePresent,	"quickTimePresent",	false, 300, true },	//		D3.1 f
 	{ kTheRandomSeed,		"randomSeed",		false, 400, false },	//			D4 p
@@ -138,6 +142,7 @@ TheEntity entities[] = {					//	hasId  ver.	isFunction
 	{ kTheRollOver,			"rollOver",			false, 500, true },	//					D5 f, undocumented
 	{ kTheRomanLingo,		"romanLingo",		false, 300, false },	//		D3.1 p
 	{ kTheRunMode, 			"runMode",			false, 500, false },//					D5 f, documented in D6
+	{ kTheScore,			"score",			false, 500, false },	//				D5 p
 	{ kTheScummvmVersion,	"scummvmVersion",	false, 200, true }, // 					ScummVM only
 	{ kTheSearchCurrentFolder,"searchCurrentFolder",false,400, true },//			D4 f
 	{ kTheSearchPath,		"searchPath",		false, 400, true },	//			D4 f
@@ -256,6 +261,16 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"sound",		kTheSound,		300 },//		D3.1 p // 0-1 off-on
 	{ kTheSprite,	"startTime",	kTheStartTime,	300 },//		D3.1 p
 	{ kTheSprite,	"stopTime",		kTheStopTime,	300 },//		D3.1 p
+	{ kTheSprite,	"trackCount",	kTheTrackCount, 500 },//					D5 p
+	{ kTheSprite,	"trackEnabled",	kTheTrackEnabled, 500 },//					D5 p
+	{ kTheSprite,	"trackNextKeyTime",	kTheTrackNextKeyTime, 500 },//					D5 p
+	{ kTheSprite,	"trackNextSampleTime",	kTheTrackNextSampleTime, 500 },//					D5 p
+	{ kTheSprite,	"trackPreviousKeyTime",	kTheTrackPreviousKeyTime, 500 },//					D5 p
+	{ kTheSprite,	"trackPreviousSampleTime",	kTheTrackPreviousKeyTime, 500 },//					D5 p
+	{ kTheSprite,	"trackStartTime",	kTheTrackStartTime, 500 },//					D5 p
+	{ kTheSprite,	"trackStopTime",	kTheTrackStopTime, 500 },//					D5 p
+	{ kTheSprite,	"trackText",	kTheTrackText, 500 },//					D5 p
+	{ kTheSprite,	"trackType",	kTheTrackType, 500 },//					D5 p
 	{ kTheCast,		"video",		kTheVideo,		400 },//				D4 p
 	{ kTheSprite,	"volume",		kTheVolume,		300 },//		D3.1 p
 
@@ -287,6 +302,7 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"lineSize",		kTheLineSize,	500 },//						D5 p
 
 	// TransitionCastMember fields
+	{ kTheCast,		"changeArea",	kTheChangeArea,	500 },//						D5 p
 	{ kTheCast,		"chunkSize",	kTheChunkSize,	500 },//						D5 p
 	{ kTheCast,		"transitionType",kTheTransitionType,500 },//					D5 p
 
@@ -307,6 +323,7 @@ const TheEntityField fields[] = {
 	{ kTheField,	"textSize",		kTheTextSize,	300 },//		D3 p
 	{ kTheField,	"textStyle",	kTheTextStyle,	300 },//		D3 p
 	{ kTheField,	"scrollTop",	kTheScrollTop,  500 },//						D5 p
+	{ kTheField,	"wordWrap",		kTheWordWrap,	500 },//						D5 p
 
 	// Chunk fields
 	{ kTheChunk,	"foreColor",	kTheForeColor,	400 },//				D4 p
@@ -529,15 +546,24 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		d.type = STRING;
 		d.u.s = score->getFrameLabel(score->getCurrentFrameNum());
 		break;
+	case kTheFramePalette:
+		d = score->getCurrentPalette().toMultiplex();
+		break;
 	case kTheFrameScript:
-		d = score->_currentFrame->_mainChannels.actionId.member;
+		d = score->_currentFrame->_mainChannels.actionId.toMultiplex();
 		break;
-	case kTheFramePalette:
-		d = score->getCurrentPalette();
+	case kTheFrameSound1:
+		d = score->_currentFrame->_mainChannels.sound1.toMultiplex();
+		break;
+	case kTheFrameSound2:
+		d = score->_currentFrame->_mainChannels.sound2.toMultiplex();
 		break;
 	case kTheFrameTempo:
 		d = score->_currentFrameRate;
 		break;
+	case kTheFrameTransition:
+		d = score->_currentFrame->_mainChannels.trans.toMultiplex();
+		break;
 	case kTheFreeBlock:
 	case kTheFreeBytes:
 		d = 32 * 1024 * 1024;	// Let's have 32 Mbytes
@@ -811,6 +837,25 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 	case kThePerFrameHook:
 		d = _perFrameHook;
 		break;
+	case kThePlatform:  // D5
+		// ScummVM doesn't track different OS versions;
+		// for now let's assume every game from D5 onwards was
+		// x86-32 or PowerPC.
+		if (g_director->getPlatform() == Common::kPlatformWindows) {
+			if (g_director->getVersion() >= 500) {
+				d = Datum("Windows,32");
+			} else {
+				d = Datum("Windows,16");
+			}
+		} else {
+			// Macintosh or pippin
+			if (g_director->getVersion() >= 500) {
+				d = Datum("Macintosh,PowerPC");
+			} else {
+				d = Datum("Macintosh,68k");
+			}
+		}
+		break;
 	case kThePreloadEventAbort:
 		d = g_lingo->_preLoadEventAbort;
 		break;
@@ -1063,16 +1108,26 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		_floatPrecisionFormat = Common::String::format("%%.%df", _floatPrecision);
 		break;
 	case kTheFrameLabel:
+		// TODO: All of these frame properties are settable during a score recording session in D5+
 		setTheEntityReadOnly(kTheFrameLabel);
 		break;
+	case kTheFramePalette:
+		setTheEntityReadOnly(kTheFramePalette);
+		break;
 	case kTheFrameScript:
 		setTheEntityReadOnly(kTheFrameScript);
 		break;
-	case kTheFramePalette:
-		setTheEntityReadOnly(kTheFramePalette);
+	case kTheFrameSound1:
+		setTheEntityReadOnly(kTheFrameSound1);
+		break;
+	case kTheFrameSound2:
+		setTheEntityReadOnly(kTheFrameSound2);
 		break;
 	case kTheFrameTempo:
-		setTheEntityReadOnly(kTheFramePalette);
+		setTheEntityReadOnly(kTheFrameTempo);
+		break;
+	case kTheFrameTransition:
+		setTheEntityReadOnly(kTheFrameTransition);
 		break;
 	case kTheFullColorPermit:
 		// No op in ScummVM. We always allow it
@@ -1155,6 +1210,9 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 	case kThePerFrameHook:
 		_perFrameHook = d;
 		break;
+	case kThePlatform:
+		setTheEntityReadOnly(kThePlatform);
+		break;
 	case kThePreloadEventAbort:
 		g_lingo->_preLoadEventAbort = bool(d.asInt());
 		break;
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index ab7c0e94b6e..c8d58be9961 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -59,7 +59,10 @@ enum TheEntityType {
 	kTheFrameLabel,
 	kTheFramePalette,
 	kTheFrameScript,
+	kTheFrameSound1,
+	kTheFrameSound2,
 	kTheFrameTempo,
+	kTheFrameTransition,
 	kTheFreeBlock,
 	kTheFreeBytes,
 	kTheFrontWindow,
@@ -112,6 +115,7 @@ enum TheEntityType {
 	kThePauseState,
 	kThePerFrameHook,
 	kThePi,
+	kThePlatform,
 	kThePreloadEventAbort,
 	kThePreLoadRAM,
 	kTheQuickTimePresent,
@@ -122,6 +126,7 @@ enum TheEntityType {
 	kTheRollOver,
 	kTheRomanLingo,
 	kTheRunMode,
+	kTheScore,
 	kTheScummvmVersion,			// set the Director version via lingo in tests
 	kTheSearchCurrentFolder,
 	kTheSearchPath,
@@ -177,6 +182,7 @@ enum TheFieldType {
 	kTheCastNum,
 	kTheCastType,
 	kTheCenter,
+	kTheChangeArea,
 	kTheCheckMark,
 	kTheChunkSize,
 	kTheConstraint,
@@ -257,6 +263,16 @@ enum TheFieldType {
 	kTheTitle,
 	kTheTitleVisible,
 	kTheTop,
+	kTheTrackCount,
+	kTheTrackEnabled,
+	kTheTrackNextKeyTime,
+	kTheTrackNextSampleTime,
+	kTheTrackPreviousKeyTime,
+	kTheTrackPreviousSampleTime,
+	kTheTrackStartTime,
+	kTheTrackStopTime,
+	kTheTrackText,
+	kTheTrackType,
 	kTheTrails,
 	kTheTransitionType,
 	kTheType,
@@ -266,6 +282,7 @@ enum TheFieldType {
 	kTheVolume,
 	kTheWidth,
 	kTheWindowType,
+	kTheWordWrap,
 	kTheScrollTop,
 	kTheMaxTheFieldType		// This must be always last
 };
diff --git a/engines/director/types.h b/engines/director/types.h
index 475481fe5d2..ee0b2792313 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -425,10 +425,14 @@ struct CastMemberID {
 	uint hash() const { return ((castLib & 0xffff) << 16) + (member & 0xffff); }
 
 	CastMemberID fromMultiplex(int multiplexID) {
+		if (multiplexID < 0)
+			return CastMemberID(multiplexID, -1);
 		return CastMemberID(multiplexID % 0x20000, 1 + (multiplexID / 0x20000));
 	}
 
 	int toMultiplex() {
+		if (castLib < 0)
+			return member;
 		return member + 0x20000 * (castLib - 1);
 	}
 };


Commit: 8d8c578b9ee8fb59f2827624111627770c4bb729
    https://github.com/scummvm/scummvm/commit/8d8c578b9ee8fb59f2827624111627770c4bb729
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add German version of winniewitch to detection table

Changed paths:
    engines/director/detection_tables.h


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 0288df0445e..149c95dc268 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -7699,6 +7699,8 @@ static const DirectorGameDescription gameDescriptions[] = {
 	WINGAME2("wine", "", "WIN95.EXE",		 "1a7acbba10a7246ba58c1d53fc7203f5", 1411337,
 						 "160MAIN.DXR",		 "23dbb4744121b077d331b01123709519", 592640, 501),
 
+	WINGAME1_l("winniewitch", "", "ZILLY.EXE", "t:f302a23d9172f018edcd4c46345c40c1", 935225, Common::DE_DEU, 501),
+
 	// Created by Human Code, Inc.
 	// Doesn't require installation
 	MACGAME1("wishbone", "", "WISHBONE/Copy2HD-power mac/Odyssey-power [hi]", "r:ae7c14ee5672c3bc9deac15a8d6d5c77", 94073, 500),


Commit: cdccd3b997361d72261ccb761c1269ca6dc27bdb
    https://github.com/scummvm/scummvm/commit/cdccd3b997361d72261ccb761c1269ca6dc27bdb
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add void check for actor perFrameHooks

Changed paths:
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index c77ff4d68a0..3d3db95a9c2 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1568,11 +1568,13 @@ void Lingo::executePerFrameHook(int frame, int subframe) {
 			for (uint i = 0; i < _actorList.u.farr->arr.size(); i++) {
 				Datum actor = _actorList.u.farr->arr[i];
 				Symbol method = actor.u.obj->getMethod("stepFrame");
-				debugC(1, kDebugLingoExec, "Executing perFrameHook : <%s>, frame %d, subframe %d", actor.asString(true).c_str(), frame, subframe);
-				if (method.nargs == 1)
-					push(actor);
-				LC::call(method, method.nargs, false);
-				execute();
+				if (method.type != VOIDSYM) {
+					debugC(1, kDebugLingoExec, "Executing perFrameHook : <%s>, frame %d, subframe %d", actor.asString(true).c_str(), frame, subframe);
+					if (method.nargs == 1)
+						push(actor);
+					LC::call(method, method.nargs, false);
+					execute();
+				}
 			}
 		}
 	}


Commit: 520d9dcedf500a58a3ad2a3502d2bd0a258e9486
    https://github.com/scummvm/scummvm/commit/520d9dcedf500a58a3ad2a3502d2bd0a258e9486
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: XOBJ: Add stubs for PrintOMatic, FileXtra and Xsound

Changed paths:
  A engines/director/lingo/xtras/filextra.cpp
  A engines/director/lingo/xtras/filextra.h
  A engines/director/lingo/xtras/xsound.cpp
  A engines/director/lingo/xtras/xsound.h
    engines/director/lingo/lingo-object.cpp
    engines/director/lingo/xlibs/printomatic.cpp
    engines/director/lingo/xlibs/printomatic.h
    engines/director/module.mk


diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 63998cf2c4f..f09aa27c8d0 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -135,10 +135,12 @@
 #include "director/lingo/xlibs/xwin.h"
 #include "director/lingo/xlibs/yasix.h"
 #include "director/lingo/xtras/directsound.h"
+#include "director/lingo/xtras/filextra.h"
 #include "director/lingo/xtras/keypoll.h"
 #include "director/lingo/xtras/qtvrxtra.h"
 #include "director/lingo/xtras/scrnutil.h"
 #include "director/lingo/xtras/timextra.h"
+#include "director/lingo/xtras/xsound.h"
 
 namespace Director {
 
@@ -247,6 +249,7 @@ static const struct XLibProto {
 	XLIBDEF(FadeGammaXCMD,		kXObj,			400),	// D4
 	XLIBDEF(FileExists,			kXObj,			300),	// D3
 	XLIBDEF(FileIO,				kXObj | kXtraObj,200),	// D2
+	XLIBDEF(FileXtra,			kXtraObj,					500),	// D5
 	XLIBDEF(FindFolder,			kXObj,			300),	// D3
 	XLIBDEF(FindSys,			kXObj,			400),	// D4
 	XLIBDEF(FindWin,			kXObj,			400),	// D4
@@ -289,7 +292,7 @@ static const struct XLibProto {
 	XLIBDEF(PopUpMenuXObj,		kXObj,			200),	// D2
 	XLIBDEF(Porta,				kXObj,			300),	// D3
 	XLIBDEF(PrefPath,			kXObj,			400),	// D4
-	XLIBDEF(PrintOMaticXObj,	kXObj,			400),	// D4
+	XLIBDEF(PrintOMaticXObj,	kXObj | kXtraObj,400),	// D4
 	XLIBDEF(ProcessXObj,		kXObj,			400),	// D4
 	XLIBDEF(QTCatMoviePlayerXObj,kXObj,			400),	// D4
 	XLIBDEF(QTMovie,			kXObj,			400),	// D4
@@ -320,6 +323,7 @@ static const struct XLibProto {
 	XLIBDEF(XWINXObj,			kXObj,			300),	// D3
 	XLIBDEF(XioXObj,			kXObj,			400),	// D3
 	XLIBDEF(XPlayAnim,			kXObj,			300),	// D3
+	XLIBDEF(XsoundXtra,			kXtraObj,					500),	// D5
 	XLIBDEF(Yasix,				kXObj,			300),	// D3
 	{ nullptr, nullptr, nullptr, 0, 0 }
 };
diff --git a/engines/director/lingo/xlibs/printomatic.cpp b/engines/director/lingo/xlibs/printomatic.cpp
index 759fa9a1a66..fa9492a533c 100644
--- a/engines/director/lingo/xlibs/printomatic.cpp
+++ b/engines/director/lingo/xlibs/printomatic.cpp
@@ -19,13 +19,24 @@
  *
  */
 
-/*************************************
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xlibs/printomatic.h"
+
+/**************************************************
  *
  * USED IN:
- * Plates are People too!
+ * Plates are People Too!
+ * I Spy
  *
- *************************************/
-/* --  PrintOMatic XObject
+ **************************************************/
+
+/*
+--  PrintOMatic XObject
 --  Version 1.1.4, August 8, 1995
 --  ©1994-95 Electronic Ink
 --
@@ -101,97 +112,263 @@ ISI    mGetPageSetup, fileName, resID
 XI     mHideMessages, trueOrFalse
 IS     mSetPageNumSymbol, symbol
 IS     mRegister, serialNumber
-*/
 
-#include "director/director.h"
-#include "director/lingo/lingo.h"
-#include "director/lingo/lingo-object.h"
-#include "director/lingo/lingo-utils.h"
-#include "director/lingo/xlibs/printomatic.h"
 
+-- xtra PrintOMatic
+--
+-- PrintOMatic Xtra
+-- Version 1.5.3
+-- Copyright 1994-97 Electronic Ink
+-- Published by g/matter, inc.
+--
+-- Product Information: http://www.gmatter.com/
+-- Technical Support & Updates: <support at gmatter.com>
+--
+--
+-- CREATE/DESTROY/RESET A DOCUMENT
+new object
+forget object
+reset object
+--
+-- DOCUMENT/JOB SETUP
+doPageSetup object      -- returns TRUE or FALSE
+doJobSetup object       -- returns TRUE or FALSE
+--
+-- DOCUMENT ATTRIBUTES
+setDocumentName object, string name
+setLandscapeMode object, boolean landscape
+setMargins object, rect margins
+setPrintableMargins object
+getPageWidth object   -- returns page width
+getPageHeight object  -- returns page height
+getPaperWidth object  -- returns paper width
+getPaperHeight object -- returns paper height
+--
+-- CREATE/SET PAGES
+newPage object -- returns page number
+setPage object, int pageNumber
+--
+-- TEXT/GRAPHIC ATTRIBUTES
+setTextFont object, string fontName -- returns TRUE if font was set
+setTextSize object, int pointSize
+setTextStyle object, string styleCodes
+setTextJust object, string justification
+setTextLineSpacing object, int spacing
+setColor object, int red, int green, int blue
+setGray object, int graylevel
+setLineWeight object, int pointSize
+--
+-- GRAPHIC ELEMENTS
+drawRect object, rect bounds, boolean filled
+drawLine object, point start, point end
+drawRoundRect object, rect bounds, int cornerRadius, boolean filled
+drawOval object, rect bounds, boolean filled
+drawText object, string text, point location
+drawPicture object, *      -- castmem or fileName, location (point or rect)
+drawStagePicture object, * -- location (point or rect), stage portion (rect)
+--
+-- CREATE FRAMES AND APPEND CONTENTS
+newFrame object, rect bounds, boolean linkedToPrevious
+append object, * any
+appendFile object, * fileName
+getInsertionPoint object -- returns string "page, x, y"
+--
+-- CUSTOMIZE THE PROGRESS BOX
+setProgressMsg object, string message
+setProgressPict object, * pictCastMember
+setProgressLoc object, point location
+--
+-- PRINT OR PREVIEW
+* printPreview *
+* print *
+--
+-- MISCELLANEOUS
+hideMessages object, boolean hide
+setPageNumSymbol object, string symbol
++ register object, string serialNumber -- returns TRUE or FALSE
++ setLowMemLimits object, globalHeap, localHeap
+
+ */
 
 namespace Director {
 
-const char *const PrintOMaticXObj::xlibName = "PrintOMatic";
+const char *PrintOMaticXObj::xlibName = "PrintOMatic";
 const XlibFileDesc PrintOMaticXObj::fileNames[] = {
-	{ "PMATIC",			nullptr },
-	{ "PrintOMatic",	nullptr },
-	{ nullptr,			nullptr },
+	{ "PrintOMatic",   nullptr },
+	{ nullptr,        nullptr },
 };
 
-static const MethodProto xlibMethods[] = {
-	{ "New",					PrintOMaticXObj::m_new,						0,	0,	400 },	// D4
-	{ "Dispose",				PrintOMaticXObj::m_dispose,					0,	0,	400 },	// D4
-	{ "Reset",					PrintOMaticXObj::m_reset,					0,	0,	400 },	// D4
-	{ "NewPage",				PrintOMaticXObj::m_newPage,					0,	0,	400 },	// D4
-	{ "SetPrintableMargins",	PrintOMaticXObj::m_setPrintableMargins,		0,	0,	400 },	// D4
-	{ "GetPageWidth",			PrintOMaticXObj::m_getPageWidth,			0,	0,	400 },	// D4
-	{ "GetPageHeight",			PrintOMaticXObj::m_getPageHeight,			0,	0,	400 },	// D4
-	{ "Picture",				PrintOMaticXObj::m_picture,					3,	5,	400 },	// D4
-	{ "StagePicture",			PrintOMaticXObj::m_stagePicture,			4,	8,	400 },	// D4
-	{ "1BitStagePicture",		PrintOMaticXObj::m_1bitStagePicture,		4,	8,	400 },	// D4
-	{ "SetLandscapeMode",		PrintOMaticXObj::m_setLandscapeMode,		1,	1,	400 },	// D4
-	{ "DoPageSetup",			PrintOMaticXObj::m_doPageSetup,				0,	0,	400 },	// D4
-	{ "DoJobSetup",				PrintOMaticXObj::m_doJobSetup,				0,	0,	400 },	// D4
-	{ "SetProgressMsg",			PrintOMaticXObj::m_setProgressMsg,			1,	1,	400 },	// D4
-	{ "PrintPreview",			PrintOMaticXObj::m_printPreview,			0,	0,	400 },	// D4
-	{ "PrintPicts",				PrintOMaticXObj::m_printPicts,				0,	1,	400 },	// D4
-	{ "Print",					PrintOMaticXObj::m_print,					0,	0,	400 },	// D4
-	{ "Register",				PrintOMaticXObj::m_register,				1,	1,	400 },	// D4
+static MethodProto xlibMethods[] = {
+	{ "new",				PrintOMaticXObj::m_new,		 0, 0,	400 },
+	{ "dispose",				PrintOMaticXObj::m_dispose,		 0, 0,	400 },
+	{ "forget",				PrintOMaticXObj::m_dispose,		 0, 0,	500 },
+	{ "reset",				PrintOMaticXObj::m_reset,		 0, 0,	400 },
+	{ "newPage",				PrintOMaticXObj::m_newPage,		 0, 0,	400 },
+	{ "setPage",				PrintOMaticXObj::m_setPage,		 1, 1,	400 },
+	{ "setMargins",				PrintOMaticXObj::m_setMargins,		 4, 4,	400 },
+	{ "setPrintableMargins",				PrintOMaticXObj::m_setPrintableMargins,		 0, 0,	400 },
+	{ "getPageWidth",				PrintOMaticXObj::m_getPageWidth,		 0, 0,	400 },
+	{ "getPageHeight",				PrintOMaticXObj::m_getPageHeight,		 0, 0,	400 },
+	{ "getPaperWidth",				PrintOMaticXObj::m_getPaperWidth,		 0, 0,	500 },
+	{ "getPaperHeight",				PrintOMaticXObj::m_getPaperHeight,		 0, 0,	500 },
+	{ "setColor",				PrintOMaticXObj::m_setColor,		 3, 3,	400 },
+	{ "setGray",				PrintOMaticXObj::m_setGray,		 1, 1,	400 },
+	{ "setPenSize",				PrintOMaticXObj::m_setPenSize,		 2, 2,	400 },
+	{ "setLineWeight",				PrintOMaticXObj::m_setLineWeight,		 1, 1,	500 },
+	{ "setTextFont",				PrintOMaticXObj::m_setTextFont,		 1, 1,	400 },
+	{ "setTextSize",				PrintOMaticXObj::m_setTextSize,		 1, 1,	400 },
+	{ "setTextStyle",				PrintOMaticXObj::m_setTextStyle,		 1, 1,	400 },
+	{ "setTextJust",				PrintOMaticXObj::m_setTextJust,		 1, 1,	400 },
+	{ "setTextLineSpacing",				PrintOMaticXObj::m_setTextLineSpacing,		 1, 1,	500 },
+	{ "textBox",				PrintOMaticXObj::m_textBox,		 5, 5,	400 },
+	{ "setText",				PrintOMaticXObj::m_setText,		 0, 0,	400 },
+	{ "appendText",				PrintOMaticXObj::m_appendText,		 0, 0,	400 },
+	{ "appendTextFile",				PrintOMaticXObj::m_appendTextFile,		 0, 0,	400 },
+	{ "append",				PrintOMaticXObj::m_appendText,		 0, 0,	500 },
+	{ "appendFile",				PrintOMaticXObj::m_appendTextFile,		 0, 0,	500 },
+	{ "appendTextResource",				PrintOMaticXObj::m_appendTextResource,		 0, 0,	400 },
+	{ "newFrame",				PrintOMaticXObj::m_newFrame,		 2, 2,	500 },
+	{ "drawRect",				PrintOMaticXObj::m_drawRect,		 2, 2,	500 },
+	{ "drawLine",				PrintOMaticXObj::m_drawLine,		 2, 2,	500 },
+	{ "drawRoundRect",				PrintOMaticXObj::m_drawRoundRect,		 3, 3,	500 },
+	{ "drawOval",				PrintOMaticXObj::m_drawOval,		 2, 2,	500 },
+	{ "drawText",				PrintOMaticXObj::m_drawText,		 3, 3,	400 },
+	{ "drawPicture",				PrintOMaticXObj::m_drawPicture,		 2, 2,	500 },
+	{ "drawStagePicture",				PrintOMaticXObj::m_drawStagePicture,		 2, 2,	500 },
+	{ "getInsertionPoint",				PrintOMaticXObj::m_getInsertionPoint,		 0, 0,	400 },
+	{ "masterTextBox",				PrintOMaticXObj::m_masterTextBox,		 4, 4,	400 },
+	{ "appendMasterText",				PrintOMaticXObj::m_appendMasterText,		 0, 0,	400 },
+	{ "appendMasterTextFiles",				PrintOMaticXObj::m_appendMasterTextFiles,		 0, 0,	400 },
+	{ "masterPictBox",				PrintOMaticXObj::m_masterPictBox,		 4, 4,	400 },
+	{ "appendMasterPict",				PrintOMaticXObj::m_appendMasterPict,		 0, 0,	400 },
+	{ "stageToMasterPict",				PrintOMaticXObj::m_stageToMasterPict,		 0, 0,	400 },
+	{ "strokedRect",				PrintOMaticXObj::m_strokedRect,		 4, 4,	400 },
+	{ "filledRect",				PrintOMaticXObj::m_filledRect,		 4, 4,	400 },
+	{ "strokedRoundRect",				PrintOMaticXObj::m_strokedRoundRect,		 5, 5,	400 },
+	{ "filledRoundRect",				PrintOMaticXObj::m_filledRoundRect,		 5, 5,	400 },
+	{ "strokedOval",				PrintOMaticXObj::m_strokedOval,		 0, 0,	400 },
+	{ "filledOval",				PrintOMaticXObj::m_filledOval,		 0, 0,	400 },
+	{ "line",				PrintOMaticXObj::m_line,		 4, 4,	400 },
+	{ "picture",				PrintOMaticXObj::m_picture,		 0, 0,	400 },
+	{ "stagePicture",				PrintOMaticXObj::m_stagePicture,		 0, 0,	400 },
+	{ "1BitStagePicture",				PrintOMaticXObj::m_1BitStagePicture,		 0, 0,	400 },
+	{ "ePSFile",				PrintOMaticXObj::m_ePSFile,		 0, 0,	400 },
+	{ "setLandscapeMode",				PrintOMaticXObj::m_setLandscapeMode,		 1, 1,	400 },
+	{ "setDocumentName",				PrintOMaticXObj::m_setDocumentName,		 1, 1,	400 },
+	{ "doPageSetup",				PrintOMaticXObj::m_doPageSetup,		 0, 0,	400 },
+	{ "doJobSetup",				PrintOMaticXObj::m_doJobSetup,		 0, 0,	400 },
+	{ "setProgressMsg",				PrintOMaticXObj::m_setProgressMsg,		 1, 1,	400 },
+	{ "setProgressPict",				PrintOMaticXObj::m_setProgressPict,		 0, 0,	400 },
+	{ "setProgressLoc",				PrintOMaticXObj::m_setProgressLoc,		 2, 2,	400 },
+	{ "printPreview",				PrintOMaticXObj::m_printPreview,		 0, 0,	400 },
+	{ "printPicts",				PrintOMaticXObj::m_printPicts,		 0, 0,	400 },
+	{ "print",				PrintOMaticXObj::m_print,		 0, 0,	400 },
+	{ "savePageSetup",				PrintOMaticXObj::m_savePageSetup,		 4, 4,	400 },
+	{ "getPageSetup",				PrintOMaticXObj::m_getPageSetup,		 2, 2,	400 },
+	{ "hideMessages",				PrintOMaticXObj::m_hideMessages,		 1, 1,	400 },
+	{ "setPageNumSymbol",				PrintOMaticXObj::m_setPageNumSymbol,		 1, 1,	400 },
+	{ "register",				PrintOMaticXObj::m_register,		 1, 1,	400 },
 	{ nullptr, nullptr, 0, 0, 0 }
 };
 
-void PrintOMaticXObj::open(ObjectType type, const Common::Path &path) {
-	if (type == kXObj) {
-		PrintOMaticXObject::initMethods(xlibMethods);
-		PrintOMaticXObject *xobj = new PrintOMaticXObject(kXObj);
-		g_lingo->exposeXObject(xlibName, xobj);
-	}
+static BuiltinProto xlibBuiltins[] = {
+
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+PrintOMaticXObject::PrintOMaticXObject(ObjectType ObjectType) :Object<PrintOMaticXObject>("PrintOMatic") {
+	_objType = ObjectType;
 }
 
-void PrintOMaticXObj::close(ObjectType type) {
-	if (type == kXObj) {
-		PrintOMaticXObject::cleanupMethods();
-		g_lingo->_globalvars[xlibName] = Datum();
-	}
+void PrintOMaticXObj::open(ObjectType type, const Common::Path &path) {
+    PrintOMaticXObject::initMethods(xlibMethods);
+    PrintOMaticXObject *xobj = new PrintOMaticXObject(type);
+    if (type == kXtraObj)
+        g_lingo->_openXtras.push_back(xlibName);
+    g_lingo->exposeXObject(xlibName, xobj);
+    g_lingo->initBuiltIns(xlibBuiltins);
 }
 
+void PrintOMaticXObj::close(ObjectType type) {
+    PrintOMaticXObject::cleanupMethods();
+    g_lingo->_globalvars[xlibName] = Datum();
 
-PrintOMaticXObject::PrintOMaticXObject(ObjectType ObjectType) :Object<PrintOMaticXObject>("PrintOMatic") {
-	_objType = ObjectType;
 }
 
 void PrintOMaticXObj::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("PrintOMaticXObj::m_new", nargs);
+	g_lingo->dropStack(nargs);
 	g_lingo->push(g_lingo->_state->me);
 }
 
 XOBJSTUBNR(PrintOMaticXObj::m_dispose)
-
-void PrintOMaticXObj::m_register(int nargs) {
-	Common::String serialNumber = g_lingo->pop().asString();
-	warning("PrintOMaticXObj::m_register: Registered with serial \"%s\"", serialNumber.c_str());
-}
-
 XOBJSTUBNR(PrintOMaticXObj::m_reset)
 XOBJSTUB(PrintOMaticXObj::m_newPage, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_setPage)
+XOBJSTUB(PrintOMaticXObj::m_setMargins, 0)
 XOBJSTUBNR(PrintOMaticXObj::m_setPrintableMargins)
-XOBJSTUB(PrintOMaticXObj::m_getPageWidth, -1)
-XOBJSTUB(PrintOMaticXObj::m_getPageHeight, -1)
-XOBJSTUBV(PrintOMaticXObj::m_picture)
-XOBJSTUBV(PrintOMaticXObj::m_stagePicture)
-XOBJSTUBV(PrintOMaticXObj::m_1bitStagePicture)
-
-void PrintOMaticXObj::m_setLandscapeMode(int nargs) {
-	// int trueOrFalse = g_lingo->pop.asInt()
-	g_lingo->printSTUBWithArglist("PrintOMaticXObj::m_setLandscapeMode", nargs);
-	g_lingo->dropStack(nargs);
-}
-
-XOBJSTUB(PrintOMaticXObj::m_doPageSetup, 1)
-XOBJSTUB(PrintOMaticXObj::m_doJobSetup, 1)
+XOBJSTUB(PrintOMaticXObj::m_getPageWidth, 0)
+XOBJSTUB(PrintOMaticXObj::m_getPageHeight, 0)
+XOBJSTUB(PrintOMaticXObj::m_getPaperWidth, 0)
+XOBJSTUB(PrintOMaticXObj::m_getPaperHeight, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_setColor)
+XOBJSTUBNR(PrintOMaticXObj::m_setGray)
+XOBJSTUBNR(PrintOMaticXObj::m_setPenSize)
+XOBJSTUBNR(PrintOMaticXObj::m_setLineWeight)
+XOBJSTUBNR(PrintOMaticXObj::m_setTextFont)
+XOBJSTUBNR(PrintOMaticXObj::m_setTextSize)
+XOBJSTUBNR(PrintOMaticXObj::m_setTextStyle)
+XOBJSTUBNR(PrintOMaticXObj::m_setTextJust)
+XOBJSTUBNR(PrintOMaticXObj::m_setTextLineSpacing)
+XOBJSTUBNR(PrintOMaticXObj::m_textBox)
+XOBJSTUB(PrintOMaticXObj::m_setText, 0)
+XOBJSTUB(PrintOMaticXObj::m_appendText, 0)
+XOBJSTUB(PrintOMaticXObj::m_appendTextFile, 0)
+XOBJSTUB(PrintOMaticXObj::m_appendTextResource, 0)
+XOBJSTUB(PrintOMaticXObj::m_newFrame, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_drawRect)
+XOBJSTUBNR(PrintOMaticXObj::m_drawLine)
+XOBJSTUBNR(PrintOMaticXObj::m_drawRoundRect)
+XOBJSTUBNR(PrintOMaticXObj::m_drawOval)
+XOBJSTUB(PrintOMaticXObj::m_drawText, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_drawPicture)
+XOBJSTUBNR(PrintOMaticXObj::m_drawStagePicture)
+XOBJSTUB(PrintOMaticXObj::m_getInsertionPoint, "page, 0, 0")
+XOBJSTUBNR(PrintOMaticXObj::m_masterTextBox)
+XOBJSTUB(PrintOMaticXObj::m_appendMasterText, 0)
+XOBJSTUB(PrintOMaticXObj::m_appendMasterTextFiles, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_masterPictBox)
+XOBJSTUB(PrintOMaticXObj::m_appendMasterPict, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_stageToMasterPict)
+XOBJSTUBNR(PrintOMaticXObj::m_strokedRect)
+XOBJSTUBNR(PrintOMaticXObj::m_filledRect)
+XOBJSTUBNR(PrintOMaticXObj::m_strokedRoundRect)
+XOBJSTUBNR(PrintOMaticXObj::m_filledRoundRect)
+XOBJSTUB(PrintOMaticXObj::m_strokedOval, 0)
+XOBJSTUB(PrintOMaticXObj::m_filledOval, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_line)
+XOBJSTUB(PrintOMaticXObj::m_picture, 0)
+XOBJSTUB(PrintOMaticXObj::m_stagePicture, 0)
+XOBJSTUB(PrintOMaticXObj::m_1BitStagePicture, 0)
+XOBJSTUB(PrintOMaticXObj::m_ePSFile, 0)
+XOBJSTUB(PrintOMaticXObj::m_setLandscapeMode, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_setDocumentName)
+XOBJSTUB(PrintOMaticXObj::m_doPageSetup, 0)
+XOBJSTUB(PrintOMaticXObj::m_doJobSetup, 0)
 XOBJSTUBNR(PrintOMaticXObj::m_setProgressMsg)
+XOBJSTUB(PrintOMaticXObj::m_setProgressPict, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_setProgressLoc)
 XOBJSTUB(PrintOMaticXObj::m_printPreview, 0)
-XOBJSTUBV(PrintOMaticXObj::m_printPicts)
+XOBJSTUB(PrintOMaticXObj::m_printPicts, 0)
 XOBJSTUBNR(PrintOMaticXObj::m_print)
+XOBJSTUB(PrintOMaticXObj::m_savePageSetup, 0)
+XOBJSTUB(PrintOMaticXObj::m_getPageSetup, 0)
+XOBJSTUBNR(PrintOMaticXObj::m_hideMessages)
+XOBJSTUB(PrintOMaticXObj::m_setPageNumSymbol, 0)
+
+void PrintOMaticXObj::m_register(int nargs) {
+	Common::String serialNumber = g_lingo->pop().asString();
+	debugC(1, kDebugXObj, "PrintOMaticXObj::m_register: Registered with serial \"%s\"", serialNumber.c_str());
+}
 
-} // End of namespace Director
+}
diff --git a/engines/director/lingo/xlibs/printomatic.h b/engines/director/lingo/xlibs/printomatic.h
index f503642ebb9..44c67b93a0a 100644
--- a/engines/director/lingo/xlibs/printomatic.h
+++ b/engines/director/lingo/xlibs/printomatic.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef DIRECTOR_LINGO_XLIBS_PRINTOMATICXOBJ_H
-#define DIRECTOR_LINGO_XLIBS_PRINTOMATICXOBJ_H
+#ifndef DIRECTOR_LINGO_XLIBS_PRINTOMATIC_H
+#define DIRECTOR_LINGO_XLIBS_PRINTOMATIC_H
 
 namespace Director {
 
@@ -31,7 +31,7 @@ public:
 
 namespace PrintOMaticXObj {
 
-extern const char *const xlibName;
+extern const char *xlibName;
 extern const XlibFileDesc fileNames[];
 
 void open(ObjectType type, const Common::Path &path);
@@ -41,19 +41,67 @@ void m_new(int nargs);
 void m_dispose(int nargs);
 void m_reset(int nargs);
 void m_newPage(int nargs);
+void m_setPage(int nargs);
+void m_setMargins(int nargs);
 void m_setPrintableMargins(int nargs);
 void m_getPageWidth(int nargs);
 void m_getPageHeight(int nargs);
+void m_getPaperWidth(int nargs);
+void m_getPaperHeight(int nargs);
+void m_setColor(int nargs);
+void m_setGray(int nargs);
+void m_setPenSize(int nargs);
+void m_setLineWeight(int nargs);
+void m_setTextFont(int nargs);
+void m_setTextSize(int nargs);
+void m_setTextStyle(int nargs);
+void m_setTextJust(int nargs);
+void m_setTextLineSpacing(int nargs);
+void m_textBox(int nargs);
+void m_setText(int nargs);
+void m_appendText(int nargs);
+void m_appendTextFile(int nargs);
+void m_appendTextResource(int nargs);
+void m_newFrame(int nargs);
+void m_drawRect(int nargs);
+void m_drawLine(int nargs);
+void m_drawRoundRect(int nargs);
+void m_drawOval(int nargs);
+void m_drawText(int nargs);
+void m_drawPicture(int nargs);
+void m_drawStagePicture(int nargs);
+void m_getInsertionPoint(int nargs);
+void m_masterTextBox(int nargs);
+void m_appendMasterText(int nargs);
+void m_appendMasterTextFiles(int nargs);
+void m_masterPictBox(int nargs);
+void m_appendMasterPict(int nargs);
+void m_stageToMasterPict(int nargs);
+void m_strokedRect(int nargs);
+void m_filledRect(int nargs);
+void m_strokedRoundRect(int nargs);
+void m_filledRoundRect(int nargs);
+void m_strokedOval(int nargs);
+void m_filledOval(int nargs);
+void m_line(int nargs);
 void m_picture(int nargs);
 void m_stagePicture(int nargs);
-void m_1bitStagePicture(int nargs);
+void m_1BitStagePicture(int nargs);
+void m_ePSFile(int nargs);
 void m_setLandscapeMode(int nargs);
+void m_setDocumentName(int nargs);
 void m_doPageSetup(int nargs);
 void m_doJobSetup(int nargs);
 void m_setProgressMsg(int nargs);
+void m_setProgressPict(int nargs);
+void m_setProgressLoc(int nargs);
 void m_printPreview(int nargs);
 void m_printPicts(int nargs);
 void m_print(int nargs);
+void m_savePageSetup(int nargs);
+void m_getPageSetup(int nargs);
+void m_hideMessages(int nargs);
+void m_setPageNumSymbol(int nargs);
 void m_register(int nargs);
 
 } // End of namespace PrintOMaticXObj
diff --git a/engines/director/lingo/xtras/filextra.cpp b/engines/director/lingo/xtras/filextra.cpp
new file mode 100644
index 00000000000..2850d81d55f
--- /dev/null
+++ b/engines/director/lingo/xtras/filextra.cpp
@@ -0,0 +1,162 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xtras/filextra.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * I Spy
+ *
+ **************************************************/
+
+/*
+-- xtra FileXtra
+-- FileXtra v2.0.4 of 18-Apr-97 by Kent Kersten
+-- Copyright (c) 1996-97 Little Planet Publishing
+-- For updates see http://www.littleplanet.com/kent/kent.html
+-- Contact the author at kent at littleplanet.com
+-- This no-charge Xtra may be freely distributed as long as it is
+-- accompanied by its documentation and sample movie.
+--
+-- Drive Functions --
+* DriveExists string driveName
+* DrivesToList
+* DriveFreeSpace string driveName
+* DriveIsCDROM string driveName
+--
+-- File Functions --
+* FileOpenDialog string initialDir, string filtStr, string dlogTitle, Boolean createPrompt, Boolean fileMustExist
+* FileSaveAsDialog string initialDir, string filename, string dlogTitle, Boolean overwritePrompt
+* FileExists string fileName
+* RenameFile string oldName, string newName
+* DeleteFile string fileName
+* CopyFile string fromFName, string toFName
+* GetFileModDate string fileName
+--
+-- Directory Functions --
+* DirectoryExists string dirName
+* CreateDirectory string dirName
+* DeleteDirectory string dirName
+* XDeleteDirectory string dirName
+* CopyDirectory string fromDirName, string toDirName
+* XCopyDirectory string fromDirName, string toDirName
+* DirectoryToList string dirName
+
+ */
+
+namespace Director {
+
+const char *FileXtra::xlibName = "File";
+const XlibFileDesc FileXtra::fileNames[] = {
+	{ "filextra",   nullptr },
+	{ nullptr,        nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+
+	{ nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+	{ "DriveExists", FileXtra::m_DriveExists, 1, 1, 500, HBLTIN },
+	{ "DrivesToList", FileXtra::m_DrivesToList, 0, 0, 500, HBLTIN },
+	{ "DriveFreeSpace", FileXtra::m_DriveFreeSpace, 1, 1, 500, HBLTIN },
+	{ "DriveIsCDROM", FileXtra::m_DriveIsCDROM, 1, 1, 500, HBLTIN },
+	{ "FileOpenDialog", FileXtra::m_FileOpenDialog, 5, 5, 500, HBLTIN },
+	{ "FileSaveAsDialog", FileXtra::m_FileSaveAsDialog, 4, 4, 500, HBLTIN },
+	{ "FileExists", FileXtra::m_FileExists, 1, 1, 500, HBLTIN },
+	{ "RenameFile", FileXtra::m_RenameFile, 2, 2, 500, HBLTIN },
+	{ "DeleteFile", FileXtra::m_DeleteFile, 1, 1, 500, HBLTIN },
+	{ "CopyFile", FileXtra::m_CopyFile, 2, 2, 500, HBLTIN },
+	{ "GetFileModDate", FileXtra::m_GetFileModDate, 1, 1, 500, HBLTIN },
+	{ "DirectoryExists", FileXtra::m_DirectoryExists, 1, 1, 500, HBLTIN },
+	{ "CreateDirectory", FileXtra::m_CreateDirectory, 1, 1, 500, HBLTIN },
+	{ "DeleteDirectory", FileXtra::m_DeleteDirectory, 1, 1, 500, HBLTIN },
+	{ "XDeleteDirectory", FileXtra::m_XDeleteDirectory, 1, 1, 500, HBLTIN },
+	{ "CopyDirectory", FileXtra::m_CopyDirectory, 2, 2, 500, HBLTIN },
+	{ "XCopyDirectory", FileXtra::m_XCopyDirectory, 2, 2, 500, HBLTIN },
+	{ "DirectoryToList", FileXtra::m_DirectoryToList, 1, 1, 500, HBLTIN },
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+FileXtraObject::FileXtraObject(ObjectType ObjectType) :Object<FileXtraObject>("File") {
+	_objType = ObjectType;
+}
+
+bool FileXtraObject::hasProp(const Common::String &propName) {
+	return (propName == "name");
+}
+
+Datum FileXtraObject::getProp(const Common::String &propName) {
+	if (propName == "name")
+		return Datum(FileXtra::xlibName);
+	warning("FileXtra::getProp: unknown property '%s'", propName.c_str());
+	return Datum();
+}
+
+void FileXtra::open(ObjectType type, const Common::Path &path) {
+    FileXtraObject::initMethods(xlibMethods);
+    FileXtraObject *xobj = new FileXtraObject(type);
+    if (type == kXtraObj)
+        g_lingo->_openXtras.push_back(xlibName);
+    g_lingo->exposeXObject(xlibName, xobj);
+    g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void FileXtra::close(ObjectType type) {
+    FileXtraObject::cleanupMethods();
+    g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void FileXtra::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("FileXtra::m_new", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUB(FileXtra::m_DriveExists, 0)
+XOBJSTUB(FileXtra::m_DrivesToList, 0)
+XOBJSTUB(FileXtra::m_DriveFreeSpace, 0)
+XOBJSTUB(FileXtra::m_DriveIsCDROM, 0)
+XOBJSTUB(FileXtra::m_FileOpenDialog, 0)
+XOBJSTUB(FileXtra::m_FileSaveAsDialog, 0)
+XOBJSTUB(FileXtra::m_FileExists, 0)
+XOBJSTUB(FileXtra::m_RenameFile, 0)
+XOBJSTUB(FileXtra::m_DeleteFile, 0)
+XOBJSTUB(FileXtra::m_CopyFile, 0)
+XOBJSTUB(FileXtra::m_GetFileModDate, 0)
+XOBJSTUB(FileXtra::m_DirectoryExists, 0)
+XOBJSTUB(FileXtra::m_CreateDirectory, 0)
+XOBJSTUB(FileXtra::m_DeleteDirectory, 0)
+XOBJSTUB(FileXtra::m_XDeleteDirectory, 0)
+XOBJSTUB(FileXtra::m_CopyDirectory, 0)
+XOBJSTUB(FileXtra::m_XCopyDirectory, 0)
+XOBJSTUB(FileXtra::m_DirectoryToList, 0)
+
+}
diff --git a/engines/director/lingo/xtras/filextra.h b/engines/director/lingo/xtras/filextra.h
new file mode 100644
index 00000000000..ff026edd00e
--- /dev/null
+++ b/engines/director/lingo/xtras/filextra.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XTRAS_FILEXTRA_H
+#define DIRECTOR_LINGO_XTRAS_FILEXTRA_H
+
+namespace Director {
+
+class FileXtraObject : public Object<FileXtraObject> {
+public:
+	FileXtraObject(ObjectType objType);
+
+	bool hasProp(const Common::String &propName) override;
+	Datum getProp(const Common::String &propName) override;
+};
+
+namespace FileXtra {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+
+void m_DriveExists(int nargs);
+void m_DrivesToList(int nargs);
+void m_DriveFreeSpace(int nargs);
+void m_DriveIsCDROM(int nargs);
+void m_FileOpenDialog(int nargs);
+void m_FileSaveAsDialog(int nargs);
+void m_FileExists(int nargs);
+void m_RenameFile(int nargs);
+void m_DeleteFile(int nargs);
+void m_CopyFile(int nargs);
+void m_GetFileModDate(int nargs);
+void m_DirectoryExists(int nargs);
+void m_CreateDirectory(int nargs);
+void m_DeleteDirectory(int nargs);
+void m_XDeleteDirectory(int nargs);
+void m_CopyDirectory(int nargs);
+void m_XCopyDirectory(int nargs);
+void m_DirectoryToList(int nargs);
+
+} // End of namespace FileXtra
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/lingo/xtras/xsound.cpp b/engines/director/lingo/xtras/xsound.cpp
new file mode 100644
index 00000000000..ef232f5fd56
--- /dev/null
+++ b/engines/director/lingo/xtras/xsound.cpp
@@ -0,0 +1,196 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+
+#include "director/director.h"
+#include "director/lingo/lingo.h"
+#include "director/lingo/lingo-object.h"
+#include "director/lingo/lingo-utils.h"
+#include "director/lingo/xtras/xsound.h"
+
+/**************************************************
+ *
+ * USED IN:
+ * I Spy
+ *
+ **************************************************/
+
+/*
+-- xtra xsound
+new object me, int bufferSize
+forget object me
+-- Sound Xtra(tm) version 3.0.1
+-- Engineered by Scott Kildall, redeye at igc.org
+-- Entire program code (c) 1995-97 by Red Eye Software
+-- Sound Xtra is a registered trademark of g/matter, inc
+-- All rights reserved.
+--
+-- For more information on Sound Xtra, see our website:
+-- http://www.gmatter.com
+--
+-- For technical support and sales, please email:
+-- <support at gmatter.com>
+-- <sales at gmatter.com>
+--
+-- Online help is available under the Xtras menu.
+--
+-- For information about other Red Eye Software products, visit
+-- the Red Eye Software website at http://www.halcyon.com/redeye
+--
++ Register object xtraRef, string serialNumber -- Registers the Sound Xtra. THIS MUST BE CALLED FOR YOUR RUNTIME (PROJECTOR) FILES
+GetError object me   -- returns the last error number
+GetInfo object me, int identifier --  returns specific information
+SetInfo object me, int identifier, int setting --  sets specific information
+Status object me   -- returns the status of a sound
+ConnectInputDevice object me -- connects to the sound recorder
+DisconnectInputDevice object me -- disconnects from the sound recorder
+SetSoundType object me, string type, string name, string action -- specifies a file for sound recording or playback
+ClearSoundType object me   -- clears information about the sound file
+Play object me   -- plays a sound
+Record object me   -- records a sound
+Stop object me   -- stops a sound
+Pause object me   -- pauses a sound
+Resume object me  -- resumes a paused sound
+GetCurrentTime object me   -- returns the playback time of a sound
+IsASound object me, string type, string name  -- indicates if this sound exists
+DeleteSound object me, string type, string name  -- deletes a sound
+SetPlaySegment object me, int start, int end  -- sets the start and end points of a playback sound
+ClearPlaySegment object me   -- resets the start and end points
+SetSampleRate object me, int rate    -- sets the sample rate of a sound
+SetSampleDepth object me, int depth   -- sets the sample depth of a sound
+SetCompression object me, int compressor   --  sets a compressor for the sound
+GetInputLevel object me   -- returns the input level of the microphone
+FreeRecordingTime object me --  returns the free recording time
+ */
+
+namespace Director {
+
+const char *XsoundXtra::xlibName = "Xsound";
+const XlibFileDesc XsoundXtra::fileNames[] = {
+	{ "xsound",   nullptr },
+	{ nullptr,        nullptr },
+};
+
+static MethodProto xlibMethods[] = {
+	{ "new",				XsoundXtra::m_new,		 1, 0,	500 },
+	{ "forget",				XsoundXtra::m_forget,		 0, 0,	500 },
+	{ "Register",				XsoundXtra::m_Register,		 1, 1,	500 },
+	{ "GetError",				XsoundXtra::m_GetError,		 0, 0,	500 },
+	{ "GetInfo",				XsoundXtra::m_GetInfo,		 1, 0,	500 },
+	{ "SetInfo",				XsoundXtra::m_SetInfo,		 2, 0,	500 },
+	{ "Status",				XsoundXtra::m_Status,		 0, 0,	500 },
+	{ "ConnectInputDevice",				XsoundXtra::m_ConnectInputDevice,		 0, 0,	500 },
+	{ "DisconnectInputDevice",				XsoundXtra::m_DisconnectInputDevice,		 0, 0,	500 },
+	{ "SetSoundType",				XsoundXtra::m_SetSoundType,		 3, 0,	500 },
+	{ "ClearSoundType",				XsoundXtra::m_ClearSoundType,		 0, 0,	500 },
+	{ "Play",				XsoundXtra::m_Play,		 0, 0,	500 },
+	{ "Record",				XsoundXtra::m_Record,		 0, 0,	500 },
+	{ "Stop",				XsoundXtra::m_Stop,		 0, 0,	500 },
+	{ "Pause",				XsoundXtra::m_Pause,		 0, 0,	500 },
+	{ "Resume",				XsoundXtra::m_Resume,		 0, 0,	500 },
+	{ "GetCurrentTime",				XsoundXtra::m_GetCurrentTime,		 0, 0,	500 },
+	{ "IsASound",				XsoundXtra::m_IsASound,		 2, 0,	500 },
+	{ "DeleteSound",				XsoundXtra::m_DeleteSound,		 2, 0,	500 },
+	{ "SetPlaySegment",				XsoundXtra::m_SetPlaySegment,		 2, 0,	500 },
+	{ "ClearPlaySegment",				XsoundXtra::m_ClearPlaySegment,		 0, 0,	500 },
+	{ "SetSampleRate",				XsoundXtra::m_SetSampleRate,		 1, 0,	500 },
+	{ "SetSampleDepth",				XsoundXtra::m_SetSampleDepth,		 1, 0,	500 },
+	{ "SetCompression",				XsoundXtra::m_SetCompression,		 1, 0,	500 },
+	{ "GetInputLevel",				XsoundXtra::m_GetInputLevel,		 0, 0,	500 },
+	{ "FreeRecordingTime",				XsoundXtra::m_FreeRecordingTime,		 0, 0,	500 },
+	{ nullptr, nullptr, 0, 0, 0 }
+};
+
+static BuiltinProto xlibBuiltins[] = {
+
+	{ nullptr, nullptr, 0, 0, 0, VOIDSYM }
+};
+
+XsoundXtraObject::XsoundXtraObject(ObjectType ObjectType) :Object<XsoundXtraObject>("Xsound") {
+	_objType = ObjectType;
+}
+
+bool XsoundXtraObject::hasProp(const Common::String &propName) {
+	return (propName == "name");
+}
+
+Datum XsoundXtraObject::getProp(const Common::String &propName) {
+	if (propName == "name")
+		return Datum(XsoundXtra::xlibName);
+	warning("XsoundXtra::getProp: unknown property '%s'", propName.c_str());
+	return Datum();
+}
+
+void XsoundXtra::open(ObjectType type, const Common::Path &path) {
+    XsoundXtraObject::initMethods(xlibMethods);
+    XsoundXtraObject *xobj = new XsoundXtraObject(type);
+    if (type == kXtraObj)
+        g_lingo->_openXtras.push_back(xlibName);
+    g_lingo->exposeXObject(xlibName, xobj);
+    g_lingo->initBuiltIns(xlibBuiltins);
+}
+
+void XsoundXtra::close(ObjectType type) {
+    XsoundXtraObject::cleanupMethods();
+    g_lingo->_globalvars[xlibName] = Datum();
+
+}
+
+void XsoundXtra::m_new(int nargs) {
+	g_lingo->printSTUBWithArglist("XsoundXtra::m_new", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(g_lingo->_state->me);
+}
+
+XOBJSTUB(XsoundXtra::m_forget, 0)
+
+void XsoundXtra::m_Register(int nargs) {
+	Common::String serialNumber = g_lingo->pop().asString();
+	debugC(1, kDebugXObj, "XsoundXtra::m_register: Registered with serial \"%s\"", serialNumber.c_str());
+	g_lingo->push(Datum(0));
+}
+
+XOBJSTUB(XsoundXtra::m_GetError, 0)
+XOBJSTUB(XsoundXtra::m_GetInfo, 0)
+XOBJSTUB(XsoundXtra::m_SetInfo, 0)
+XOBJSTUB(XsoundXtra::m_Status, 0)
+XOBJSTUB(XsoundXtra::m_ConnectInputDevice, 0)
+XOBJSTUB(XsoundXtra::m_DisconnectInputDevice, 0)
+XOBJSTUB(XsoundXtra::m_SetSoundType, 0)
+XOBJSTUB(XsoundXtra::m_ClearSoundType, 0)
+XOBJSTUB(XsoundXtra::m_Play, 0)
+XOBJSTUB(XsoundXtra::m_Record, 0)
+XOBJSTUB(XsoundXtra::m_Stop, 0)
+XOBJSTUB(XsoundXtra::m_Pause, 0)
+XOBJSTUB(XsoundXtra::m_Resume, 0)
+XOBJSTUB(XsoundXtra::m_GetCurrentTime, 0)
+XOBJSTUB(XsoundXtra::m_IsASound, 0)
+XOBJSTUB(XsoundXtra::m_DeleteSound, 0)
+XOBJSTUB(XsoundXtra::m_SetPlaySegment, 0)
+XOBJSTUB(XsoundXtra::m_ClearPlaySegment, 0)
+XOBJSTUB(XsoundXtra::m_SetSampleRate, 0)
+XOBJSTUB(XsoundXtra::m_SetSampleDepth, 0)
+XOBJSTUB(XsoundXtra::m_SetCompression, 0)
+XOBJSTUB(XsoundXtra::m_GetInputLevel, 0)
+XOBJSTUB(XsoundXtra::m_FreeRecordingTime, 0)
+
+}
diff --git a/engines/director/lingo/xtras/xsound.h b/engines/director/lingo/xtras/xsound.h
new file mode 100644
index 00000000000..6159e15fead
--- /dev/null
+++ b/engines/director/lingo/xtras/xsound.h
@@ -0,0 +1,74 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef DIRECTOR_LINGO_XTRAS_XSOUND_H
+#define DIRECTOR_LINGO_XTRAS_XSOUND_H
+
+namespace Director {
+
+class XsoundXtraObject : public Object<XsoundXtraObject> {
+public:
+	XsoundXtraObject(ObjectType objType);
+
+	bool hasProp(const Common::String &propName) override;
+	Datum getProp(const Common::String &propName) override;
+};
+
+namespace XsoundXtra {
+
+extern const char *xlibName;
+extern const XlibFileDesc fileNames[];
+
+void open(ObjectType type, const Common::Path &path);
+void close(ObjectType type);
+
+void m_new(int nargs);
+void m_forget(int nargs);
+void m_Register(int nargs);
+void m_GetError(int nargs);
+void m_GetInfo(int nargs);
+void m_SetInfo(int nargs);
+void m_Status(int nargs);
+void m_ConnectInputDevice(int nargs);
+void m_DisconnectInputDevice(int nargs);
+void m_SetSoundType(int nargs);
+void m_ClearSoundType(int nargs);
+void m_Play(int nargs);
+void m_Record(int nargs);
+void m_Stop(int nargs);
+void m_Pause(int nargs);
+void m_Resume(int nargs);
+void m_GetCurrentTime(int nargs);
+void m_IsASound(int nargs);
+void m_DeleteSound(int nargs);
+void m_SetPlaySegment(int nargs);
+void m_ClearPlaySegment(int nargs);
+void m_SetSampleRate(int nargs);
+void m_SetSampleDepth(int nargs);
+void m_SetCompression(int nargs);
+void m_GetInputLevel(int nargs);
+void m_FreeRecordingTime(int nargs);
+
+} // End of namespace XsoundXtra
+
+} // End of namespace Director
+
+#endif
diff --git a/engines/director/module.mk b/engines/director/module.mk
index acf3950056e..1396616f96d 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -164,10 +164,12 @@ MODULE_OBJS = \
 	lingo/xlibs/xwin.o \
 	lingo/xlibs/yasix.o \
 	lingo/xtras/directsound.o \
+	lingo/xtras/filextra.o \
 	lingo/xtras/keypoll.o \
 	lingo/xtras/qtvrxtra.o \
 	lingo/xtras/scrnutil.o \
-	lingo/xtras/timextra.o
+	lingo/xtras/timextra.o \
+	lingo/xtras/xsound.o
 
 
 ifdef USE_IMGUI


Commit: c4a3134d9be92698cdb41702265c0769ac16d974
    https://github.com/scummvm/scummvm/commit/c4a3134d9be92698cdb41702265c0769ac16d974
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add detection entry for Plates are People Too!

Changed paths:
    engines/director/detection_tables.h


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index 149c95dc268..61362cb4112 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -401,6 +401,7 @@ static const PlainGameDescriptor directorGames[] = {
 	{ "pingu2",				"Pingu and Friends" },
 	{ "pippi",				"Astrid Lindgren's Pippi" },
 	{ "planetarizona",		"Escape from Planet Arizona" },
+	{ "plates",				"Plates are People Too!" },
 	{ "playroom",			"The Playroom" },
 	{ "plbible",			"The Play & Learn Children's Bible On CD-ROM" },
 	{ "poohac",				"Winnie the Pooh Activity Center" },
@@ -5540,6 +5541,8 @@ static const DirectorGameDescription gameDescriptions[] = {
 	WINDEMO2("planetearth", "Demo", "PLANETE.EXE",	"t:1ab2d4f204eb42c9a8ff5257f7cef149", 690069,
 									"INTRO.DIR",	"f:44456604551f5670f801fc69cbbe5833", 10175740, 404),
 
+	MACGAME1("plates", "", "xn--        Plates        -/Plates Are People Too!", "r:bcd068aaac1177eab7125ea39f66e86f", 483518, 400),
+
 	// Found on the Play-Doh Creations CD
 	MACGAME1("playskool", "", "goHIGmem PPC", "r:a6043fbba9186296faf8a2b82e5e4182",    64250, 404),
 	WINGAME2("playskool", "", "SAMPLER.EXE",  "t:4de224099dd6f16d5c9892f94c975f2a",   696951,


Commit: ab5eb6425fb9f1a0d0f7ceeafe4df80a6cfe52be
    https://github.com/scummvm/scummvm/commit/ab5eb6425fb9f1a0d0f7ceeafe4df80a6cfe52be
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DEVTOOLS: Add textfile support to director-generate-xobj-stub.py

Changed paths:
    devtools/director-generate-xobj-stub.py


diff --git a/devtools/director-generate-xobj-stub.py b/devtools/director-generate-xobj-stub.py
index 6c0f21d2f4b..9fd897b0549 100755
--- a/devtools/director-generate-xobj-stub.py
+++ b/devtools/director-generate-xobj-stub.py
@@ -590,6 +590,8 @@ def extract_xcode_win32(file: BinaryIO, pe_offset: int) -> XCode:
     # Lingo Xtras are COM libraries with a generic calling API.
     # Director discovers what functions are available by requesting
     # a msgTable, which unfortunately for us is done with code.
+
+    # Search for the basic case of passing xtra_methtable as a static C string.
     # We need to find the following x86 assembly:
     # 68 [ u32 addr 1 ]  ; push offset "msgTable"
     # 6a 00              ; push 0
@@ -626,6 +628,7 @@ def extract_xcode_win32(file: BinaryIO, pe_offset: int) -> XCode:
                 end = data.find(b"\x00", start)
                 methtable_found = True
                 methtable = data[start:end].decode('iso-8859-1').split('\n')
+
     if not methtable_found:
         raise ValueError("Could not find msgTable!")
 
@@ -644,6 +647,38 @@ def extract_xcode_win32(file: BinaryIO, pe_offset: int) -> XCode:
     }
 
 
+def extract_xcode_textfile(file: BinaryIO) -> XCode:
+    # For Xtras, it is entirely possible for the msgTable to be
+    # generated at runtime. In these unlucky cases, your only option
+    # is to load the Xtra into real Director and run
+    #
+    # put mMessageList(xtra("xtraName"))
+    #
+    # then manually copy and save the output to a text file encoded as UTF8.
+
+    file.seek(0)
+
+    # skip past the useless marker Microsoft Notepad appends to UTF8 files
+    if file.read(3) != b"\xef\xbb\xbf":
+        file.seek(0)
+
+    data = file.read().decode("utf8")
+    separator = "\r\n" if "\r\n" in data else "\n"
+
+    methtable = data.split(separator)
+
+    library_name = methtable[0].split()[1].capitalize()
+    methtable[0] = "-- " + methtable[0]
+
+    return {
+        "type": "Xtra",
+        "name": library_name,
+        "slug": library_name.lower(),
+        "filename": library_name.lower(),
+        "method_table": methtable
+    }
+
+
 def extract_xcode(path: str, resid: str) -> XCode:
     with open(path, "rb") as file:
         magic = file.read(0x2)
@@ -679,7 +714,10 @@ def extract_xcode(path: str, resid: str) -> XCode:
             )
             print(f"resource offset: {resource_offset}")
             return extract_xcode_macbinary(file, resource_offset, resid)
-
+        if path.endswith(".txt"):
+            # there's probably a more legit way of checking for text files
+            print("Found text file!")
+            return extract_xcode_textfile(file)
     raise ValueError("Unknown filetype")
 
 


Commit: 5003d8769f4a09fe8902a530275b204ba498faac
    https://github.com/scummvm/scummvm/commit/5003d8769f4a09fe8902a530275b204ba498faac
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: LINGO: Improve support for D5-style CastMemberID decoding

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-bytecode.cpp
    engines/director/lingo/lingo-code.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 805e4748bf3..535073df20a 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3385,35 +3385,15 @@ void LB::b_castLib(int nargs) {
 
 void LB::b_member(int nargs) {
 	Movie *movie = g_director->getCurrentMovie();
-	CastMemberID res;
+	Datum library;
+	Datum member;
 	if (nargs == 1) {
-		Datum member = g_lingo->pop();
-		if (member.isCastRef()) {
-			res = member.asMemberID();
-		} else if (member.isNumeric()) {
-			res = movie->getCastMemberIDByMember(member.asInt());
-		} else {
-			res = movie->getCastMemberIDByName(member.asString());
-		}
+		member = g_lingo->pop();
 	} else if (nargs == 2) {
-		Datum library = g_lingo->pop();
-		Datum member = g_lingo->pop();
-		int libId = -1;
-		if (library.type == CASTLIBREF) {
-			libId = library.u.i;
-		} else if (library.isNumeric()) {
-			libId = library.asInt();
-		} else {
-			libId = movie->getCastLibIDByName(library.asString());
-		}
-		if (member.isCastRef()) {
-			res = member.asMemberID();
-		} else if (member.isNumeric()) {
-			res = CastMemberID(member.asInt(), libId);
-		} else {
-			res = movie->getCastMemberIDByNameAndType(member.asString(), libId, kCastTypeAny);
-		}
+		library = g_lingo->pop();
+		member = g_lingo->pop();
 	}
+	CastMemberID res = g_lingo->toCastMemberID(member, library);
 	if (!movie->getCastMember(res)) {
 		g_lingo->lingoError("No match found for cast member");
 		return;
diff --git a/engines/director/lingo/lingo-bytecode.cpp b/engines/director/lingo/lingo-bytecode.cpp
index af1c5de4edf..4f26b7f4b2b 100644
--- a/engines/director/lingo/lingo-bytecode.cpp
+++ b/engines/director/lingo/lingo-bytecode.cpp
@@ -391,8 +391,8 @@ Datum Lingo::findVarV4(int varType, const Datum &id) {
 		if (g_director->getVersion() < 500) {
 			res = id.asMemberID();
 		} else {
-			Datum castName = g_lingo->pop();
-			res = castName.asMemberID(kCastTypeAny, id.asInt());
+			Datum member = g_lingo->pop();
+			res = g_lingo->toCastMemberID(member, id);
 		}
 		res.type = FIELDREF;
 		break;
@@ -747,10 +747,11 @@ void LC::cb_v4theentitypush() {
 		case kTEAItemId:
 			{
 				Datum id = g_lingo->pop();
-				if (entity == kTheCast && g_director->getVersion() >= 500) {
+				if ((entity == kTheCast || entity == kTheField) && g_director->getVersion() >= 500) {
 					// For "the member", D5 and above have a lib ID followed by a member ID
 					// Pre-resolve them here.
-					CastMemberID resolved = g_lingo->resolveCastMember(g_lingo->pop(), id, kCastTypeAny);
+					Datum member = g_lingo->pop();
+					CastMemberID resolved = g_lingo->toCastMemberID(member, id);
 					id = Datum(resolved);
 				}
 				debugC(3, kDebugLingoExec, "cb_v4theentitypush: calling getTheEntity(%s, %s, %s)", g_lingo->entity2str(entity), id.asString(true).c_str(), g_lingo->field2str(field));
@@ -907,6 +908,13 @@ void LC::cb_v4theentityassign() {
 	case kTEAItemId:
 		{
 			Datum id = g_lingo->pop();
+			if ((entity == kTheCast || entity == kTheField) && g_director->getVersion() >= 500) {
+				// For "the member", D5 and above have a lib ID followed by a member ID
+				// Pre-resolve them here.
+				Datum member = g_lingo->pop();
+				CastMemberID resolved = g_lingo->toCastMemberID(member, id);
+				id = Datum(resolved);
+			}
 			debugC(3, kDebugLingoExec, "cb_v4theentityassign: calling setTheEntity(%s, %s, %s, %s)", g_lingo->entity2str(entity), id.asString(true).c_str(), g_lingo->field2str(field), value.asString(true).c_str());
 			g_lingo->setTheEntity(entity, id, field, value);
 		}
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index e74194f79b9..f61cdc54732 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -1936,7 +1936,7 @@ void LC::c_fieldref() {
 	if (g_director->getVersion() >= 500)
 		castLib = g_lingo->pop();
 	Datum member = g_lingo->pop();
-	Datum res = member.asMemberID(kCastTypeAny, castLib.asInt());
+	Datum res = g_lingo->toCastMemberID(member, castLib);
 	res.type = FIELDREF;
 	g_lingo->push(res);
 }
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 3d3db95a9c2..118e6affd59 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1921,6 +1921,49 @@ CastMemberID Lingo::resolveCastMember(const Datum &memberID, const Datum &castLi
 	return CastMemberID(-1, castLib.asInt());
 }
 
+CastMemberID Lingo::toCastMemberID(const Datum &member, const Datum &castLib) {
+	// Used specifically for unpacking CastMemberIDs when provided by the bytecode
+	// as two Datums. This means no multiplex IDs.
+	Movie *movie = g_director->getCurrentMovie();
+	if (!movie) {
+		warning("Lingo::toCastMemberID: No movie set");
+		return CastMemberID(-1, 0);
+	}
+	CastMemberID res;
+	if (castLib.type == VOID) {
+		if (member.isCastRef()) {
+			res = member.asMemberID();
+		} else if (member.isNumeric()) {
+			res = movie->getCastMemberIDByMember(member.asInt());
+		} else {
+			res = movie->getCastMemberIDByName(member.asString());
+		}
+	} else {
+		int libId = -1;
+		if (castLib.type == CASTLIBREF) {
+			libId = castLib.u.i;
+		} else if (castLib.isNumeric()) {
+			libId = castLib.asInt();
+		} else {
+			libId = movie->getCastLibIDByName(castLib.asString());
+		}
+		if (member.isCastRef()) {
+			res = member.asMemberID();
+		} else if (member.isNumeric()) {
+			if (libId == 0) {
+				// When specifying 0 as the castlib, D5 will assume this
+				// means the default (i.e. first) cast library. It will not
+				// try other libraries for matches if the member is a number.
+				libId = DEFAULT_CAST_LIB;
+			}
+			res = CastMemberID(member.asInt(), libId);
+		} else {
+			res = movie->getCastMemberIDByNameAndType(member.asString(), libId, kCastTypeAny);
+		}
+	}
+	return res;
+}
+
 void Lingo::exposeXObject(const char *name, Datum obj) {
 	_globalvars[name] = obj;
 	_globalvars[name].ignoreGlobal = true;
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index f9c7b044e92..7118c611105 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -419,6 +419,7 @@ public:
 	Common::U32String evalChunkRef(const Datum &var);
 	Datum findVarV4(int varType, const Datum &id);
 	CastMemberID resolveCastMember(const Datum &memberID, const Datum &castLib, CastType type);
+	CastMemberID toCastMemberID(const Datum &member, const Datum &castLib);
 	void exposeXObject(const char *name, Datum obj);
 
 	int getAlignedType(const Datum &d1, const Datum &d2, bool equality);


Commit: 2397091adf403fcd1364a6dfcdd09be3e27503ae
    https://github.com/scummvm/scummvm/commit/2397091adf403fcd1364a6dfcdd09be3e27503ae
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: LINGO: Add stubs for new D5 builtin functions

Changed paths:
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-builtins.h


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 535073df20a..ecd78db8555 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -111,6 +111,7 @@ static const BuiltinProto builtins[] = {
 	{ "openDA",	 		LB::b_openDA, 		1, 1, 200, CBLTIN },	// D2 c
 	{ "openResFile",	LB::b_openResFile,	1, 1, 200, CBLTIN },	// D2 c
 	{ "openXlib",		LB::b_openXlib,		1, 1, 200, CBLTIN },	// D2 c
+	{ "save",			LB::b_save,			1, 1, 500, CBLTIN },	//				D5 c
 	{ "saveMovie",		LB::b_saveMovie,	0, 1, 400, CBLTIN },	//			D4 c
 	{ "setCallBack",	LB::b_setCallBack,	2, 2, 200, CBLTIN },	// D2 c
 	{ "showResFile",	LB::b_showResFile,	0, 1, 200, CBLTIN },	// D2 c
@@ -119,12 +120,15 @@ static const BuiltinProto builtins[] = {
 	{ "xtra",			LB::b_xtra,			1, 1, 500, FBLTIN },	//				D5 f
 	// Control
 	{ "abort",			LB::b_abort,		0, 0, 400, CBLTIN },	//			D4 c
+	{ "cancelIdleLoad",	LB::b_cancelIdleLoad,1, 1, 500, CBLTIN },	//				D5 c
 	{ "continue",		LB::b_continue,		0, 0, 200, CBLTIN },	// D2 c
 	{ "dontPassEvent",	LB::b_dontPassEvent,0, 0, 200, CBLTIN },	// D2 c
 	{ "delay",	 		LB::b_delay,		1, 1, 200, CBLTIN },	// D2 c
 	{ "do",		 		LB::b_do,			1, 1, 200, CBLTIN },	// D2 c
+	{ "finishIdleLoad",	LB::b_finishIdleLoad,1, 1, 500, CBLTIN },	//				D5 c
 	{ "go",		 		LB::b_go,			1, 2, 200, CBLTIN },	// D2 c
 	{ "halt",	 		LB::b_halt,			0, 0, 400, CBLTIN },	//			D4 c
+	{ "idleLoadDone",	LB::b_idleLoadDone,	1, 1, 500, FBLTIN },	//				D5 f
 	{ "nothing",		LB::b_nothing,		0, 0, 200, CBLTIN },	// D2 c
 	{ "pass",			LB::b_pass,			0, 0, 400, CBLTIN },	//			D4 c
 	{ "pause",			LB::b_pause,		0, 0, 200, CBLTIN },	// D2 c
@@ -134,6 +138,7 @@ static const BuiltinProto builtins[] = {
 	{ "preLoad",		LB::b_preLoad,		-1,0, 300, CBLTIN },	//		D3.1 c
 	{ "preLoadCast",	LB::b_preLoadCast,	-1,0, 300, CBLTIN },	//		D3.1 c
 	{ "preLoadMember",	LB::b_preLoadCast,	-1,0, 500, CBLTIN },	//				D5 c
+	{ "preLoadMovie",	LB::b_preLoadMovie,	1, 1, 500, CBLTIN },	//				D5 c
 	{ "quit",			LB::b_quit,			0, 0, 200, CBLTIN },	// D2 c
 	{ "restart",		LB::b_restart,		0, 0, 200, CBLTIN },	// D2 c
 	{ "return",			LB::b_return,		0, 1, 200, CBLTIN },	// D2 f
@@ -192,9 +197,16 @@ static const BuiltinProto builtins[] = {
 	{ "unLoad",			LB::b_unLoad,		0, 2, 300, CBLTIN },	//		D3.1 c
 	{ "unLoadCast",		LB::b_unLoadCast,	0, 2, 300, CBLTIN },	//		D3.1 c
 	{ "unLoadMember",	LB::b_unLoadCast,	0, 2, 500, CBLTIN },	//				D5 c
+	{ "unLoadMovie",	LB::b_unLoadMovie,	1, 1, 500, CBLTIN },	//				D5 c
 	{ "updateStage",	LB::b_updateStage,	0, 0, 200, CBLTIN },	// D2 c
 	{ "zoomBox",		LB::b_zoomBox,		-1,0, 200, CBLTIN },	// D2 c
 	{"immediateSprite", LB::b_immediateSprite, -1, 0, 200, CBLTIN}, // D2 c
+	// Score recording
+	{ "clearFrame",		LB::b_clearFrame,	0, 0, 500, CBLTIN },	//				D5 c
+	{ "deleteFrame",	LB::b_deleteFrame,	0, 0, 500, CBLTIN },	//				D5 c
+	{ "duplicateFrame",	LB::b_duplicateFrame,0, 0, 500, CBLTIN },	//				D5 c
+	{ "insertFrame",	LB::b_insertFrame,	0, 0, 500, CBLTIN },	//				D5 c
+	{ "updateFrame",	LB::b_updateFrame,	0, 0, 500, CBLTIN },	//				D5 c
 	// Point
 	{ "point",			LB::b_point,		2, 2, 400, FBLTIN },	//			D4 f
 	{ "inside",			LB::b_inside,		2, 2, 400, FBLTIN },	//			D4 f
@@ -224,6 +236,14 @@ static const BuiltinProto builtins[] = {
 	{ "member",			LB::b_member,		1, 2, 500, FBLTIN },	//				D5 f
 	{ "script",			LB::b_script,		1, 1, 400, FBLTIN },	//			D4 f
 	{ "window",			LB::b_window,		1, 1, 400, FBLTIN },	//			D4 f
+	{ "windowPresent",	LB::b_windowPresent,1, 1, 500, FBLTIN },	//				D5 f
+	// Field operations
+	{ "charPosToLoc",	LB::b_charPosToLoc, 2, 2, 500, FBLTIN },	//				D5 f
+	{ "linePosToLocV",	LB::b_linePosToLocV,2, 2, 500, FBLTIN },	//				D5 f
+	{ "locToCharPos",	LB::b_locToCharPos, 2, 2, 500, FBLTIN },	//				D5 f
+	{ "locVToLinePos",	LB::b_locVToLinePos, 2, 2, 500, FBLTIN },	//				D5 f
+	{ "scrollByLine",	LB::b_scrollByLine, 2, 2, 500, CBLTIN },	//				D5 c
+	{ "scrollByPage",	LB::b_scrollByPage, 2, 2, 500, CBLTIN },	//				D5 c
 	// Chunk operations
 	{ "numberOfChars",	LB::b_numberofchars,1, 1, 300, FBLTIN },	//			D3 f
 	{ "numberOfItems",	LB::b_numberofitems,1, 1, 300, FBLTIN },	//			D3 f
@@ -1466,6 +1486,12 @@ void LB::b_openXlib(int nargs) {
 	}
 }
 
+void LB::b_save(int nargs) {
+	g_lingo->printSTUBWithArglist("b_save", nargs);
+
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_saveMovie(int nargs) {
 	g_lingo->printSTUBWithArglist("b_saveMovie", nargs);
 
@@ -1533,6 +1559,11 @@ void LB::b_abort(int nargs) {
 	g_lingo->_abort = true;
 }
 
+void LB::b_cancelIdleLoad(int nargs) {
+	g_lingo->printSTUBWithArglist("b_cancelIdleLoad", nargs);
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_continue(int nargs) {
 	g_director->_playbackPaused = false;
 }
@@ -1569,6 +1600,11 @@ void LB::b_do(int nargs) {
 	LC::call(sym, 0, false);
 }
 
+void LB::b_finishIdleLoad(int nargs) {
+	g_lingo->printSTUBWithArglist("b_finishIdleLoad", nargs);
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_go(int nargs) {
 	// Builtin function for go as used by the Director bytecode engine.
 	//
@@ -1641,6 +1677,13 @@ void LB::b_halt(int nargs) {
 	warning("Movie halted");
 }
 
+void LB::b_idleLoadDone(int nargs) {
+	g_lingo->printSTUBWithArglist("b_idleLoadDone", nargs);
+	g_lingo->dropStack(nargs);
+	Datum res(1);
+	g_lingo->push(res);
+}
+
 void LB::b_pass(int nargs) {
 	g_lingo->_passEvent = true;
 }
@@ -1717,6 +1760,11 @@ void LB::b_preLoadCast(int nargs) {
 		g_lingo->pop();
 }
 
+void LB::b_preLoadMovie(int nargs) {
+	g_lingo->printSTUBWithArglist("b_preLoadMovie", nargs);
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_framesToHMS(int nargs) {
 	int fractionalSeconds = g_lingo->pop().asInt();
 	int dropFrame = g_lingo->pop().asInt();
@@ -2897,6 +2945,11 @@ void LB::b_unLoadCast(int nargs) {
 	g_lingo->dropStack(nargs);
 }
 
+void LB::b_unLoadMovie(int nargs) {
+	g_lingo->printSTUBWithArglist("b_unLoadMovie", nargs);
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_zoomBox(int nargs) {
 	// zoomBox startSprite, endSprite [, delatTicks]
 	//   ticks are in 1/60th, default 1
@@ -3017,6 +3070,34 @@ void LB::b_updateStage(int nargs) {
 	}
 }
 
+///////////////////
+// Score recording
+///////////////////
+
+void LB::b_clearFrame(int nargs) {
+	g_lingo->printSTUBWithArglist("b_clearFrame", nargs);
+	g_lingo->dropStack(nargs);
+}
+
+void LB::b_deleteFrame(int nargs) {
+	g_lingo->printSTUBWithArglist("b_deleteFrame", nargs);
+	g_lingo->dropStack(nargs);
+}
+
+void LB::b_duplicateFrame(int nargs) {
+	g_lingo->printSTUBWithArglist("b_duplicateFrame", nargs);
+	g_lingo->dropStack(nargs);
+}
+
+void LB::b_insertFrame(int nargs) {
+	g_lingo->printSTUBWithArglist("b_insertFrame", nargs);
+	g_lingo->dropStack(nargs);
+}
+
+void LB::b_updateFrame(int nargs) {
+	g_lingo->printSTUBWithArglist("b_updateFrame", nargs);
+	g_lingo->dropStack(nargs);
+}
 
 ///////////////////
 // Point
@@ -3462,6 +3543,50 @@ void LB::b_window(int nargs) {
 	g_lingo->push(window);
 }
 
+void LB::b_windowPresent(int nargs) {
+	g_lingo->printSTUBWithArglist("b_windowPresent", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(Datum(1));
+}
+
+void LB::b_charPosToLoc(int nargs) {
+	g_lingo->printSTUBWithArglist("b_charPosToLoc", nargs);
+	g_lingo->dropStack(nargs);
+	Datum res(Common::Point(0, 0));
+	g_lingo->push(res);
+}
+
+void LB::b_linePosToLocV(int nargs) {
+	g_lingo->printSTUBWithArglist("b_linePosToLocV", nargs);
+	g_lingo->dropStack(nargs);
+	Datum res(0);
+	g_lingo->push(res);
+}
+
+void LB::b_locToCharPos(int nargs) {
+	g_lingo->printSTUBWithArglist("b_locToCharPos", nargs);
+	g_lingo->dropStack(nargs);
+	Datum res(0);
+	g_lingo->push(res);
+}
+
+void LB::b_locVToLinePos(int nargs) {
+	g_lingo->printSTUBWithArglist("b_locVToLinePos", nargs);
+	g_lingo->dropStack(nargs);
+	Datum res(0);
+	g_lingo->push(res);
+}
+
+void LB::b_scrollByLine(int nargs) {
+	g_lingo->printSTUBWithArglist("b_scrollByLine", nargs);
+	g_lingo->dropStack(nargs);
+}
+
+void LB::b_scrollByPage(int nargs) {
+	g_lingo->printSTUBWithArglist("b_scrollByPage", nargs);
+	g_lingo->dropStack(nargs);
+}
+
 void LB::b_numberofchars(int nargs) {
 	Datum d = g_lingo->pop();
 	Datum chunkRef = LC::lastChunk(kChunkChar, d);
diff --git a/engines/director/lingo/lingo-builtins.h b/engines/director/lingo/lingo-builtins.h
index 8014e9c520c..a00b522757f 100644
--- a/engines/director/lingo/lingo-builtins.h
+++ b/engines/director/lingo/lingo-builtins.h
@@ -121,17 +121,27 @@ void b_rollOver(int nargs);
 void b_spriteBox(int nargs);
 void b_unLoad(int nargs);
 void b_unLoadCast(int nargs);
+void b_unLoadMovie(int nargs);
 void b_updateStage(int nargs);
 void b_zoomBox(int nargs);
 void b_immediateSprite(int nargs);
 
+void b_clearFrame(int nargs);
+void b_deleteFrame(int nargs);
+void b_duplicateFrame(int nargs);
+void b_insertFrame(int nargs);
+void b_updateFrame(int nargs);
+
 void b_abort(int nargs);
+void b_cancelIdleLoad(int nargs);
 void b_continue(int nargs);
 void b_dontPassEvent(int nargs);
 void b_delay(int nargs);
 void b_do(int nargs);
+void b_finishIdleLoad(int nargs);
 void b_go(int nargs);
 void b_halt(int nargs);
+void b_idleLoadDone(int nargs);
 void b_nothing(int nargs);
 void b_pass(int nargs);
 void b_pause(int nargs);
@@ -139,6 +149,7 @@ void b_play(int nargs);
 void b_playAccel(int nargs);
 void b_preLoad(int nargs);
 void b_preLoadCast(int nargs);
+void b_preLoadMovie(int nargs);
 void b_quit(int nargs);
 void b_restart(int nargs);
 void b_shutDown(int nargs);
@@ -154,6 +165,7 @@ void b_openDA(int nargs);
 void b_openResFile(int nargs);
 void b_openXlib(int nargs);
 void b_setCallBack(int nargs);
+void b_save(int nargs);
 void b_saveMovie(int nargs);
 void b_showResFile(int nargs);
 void b_showXlib(int nargs);
@@ -170,6 +182,7 @@ void b_union(int nargs);
 
 void b_member(int nargs);
 void b_window(int nargs);
+void b_windowPresent(int nargs);
 
 void b_beep(int nargs);
 void b_mci(int nargs);
@@ -191,6 +204,13 @@ void b_cast(int nargs);
 void b_castLib(int nargs);
 void b_script(int nargs);
 
+void b_charPosToLoc(int nargs);
+void b_linePosToLocV(int nargs);
+void b_locToCharPos(int nargs);
+void b_locVToLinePos(int nargs);
+void b_scrollByLine(int nargs);
+void b_scrollByPage(int nargs);
+
 void b_numberofchars(int nargs);
 void b_numberofitems(int nargs);
 void b_numberoflines(int nargs);


Commit: a529f6db4d086f3e5bb7bf80b40675ab54ac527c
    https://github.com/scummvm/scummvm/commit/a529f6db4d086f3e5bb7bf80b40675ab54ac527c
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add entities/fields new to Director 5

Changed paths:
    engines/director/castmember/text.cpp


diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index ffe447705a6..27f5b82798c 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -482,6 +482,7 @@ bool TextCastMember::hasField(int field) {
 	case kTheBorder:
 	case kTheScrollTop:
 	case kTheWordWrap:
+	case kTheEditable:
 		return _type == kCastText;
 	case kTheButtonType:
 		return _type == kCastButton;
@@ -537,6 +538,13 @@ Datum TextCastMember::getField(int field) {
 	case kTheScrollTop:
 		d = _scroll;
 		break;
+	case kTheWordWrap:
+		warning("STUB: TextCastMember::getField(): wordWrap not implemented");
+		d = 1;
+		break;
+	case kTheEditable:
+		d = (int)_editable;
+		break;
 	case kTheButtonType:
 		switch (_buttonType) {
 		case kTypeCheckBox:
@@ -554,8 +562,6 @@ Datum TextCastMember::getField(int field) {
 			break;
 		}
 		break;
-	case kTheWordWrap:
-		return _type == kCastText;
 	default:
 		d = CastMember::getField(field);
 	}
@@ -659,11 +665,19 @@ bool TextCastMember::setField(int field, const Datum &d) {
 		_ptext = ((Graphics::MacText *)toEdit->_widget)->getPlainText();
 		_ftext = ((Graphics::MacText *)toEdit->_widget)->getTextChunk(0, 0, -1, -1, true);
 		return true;
+	case kTheBorder:
+		_borderSize = d.asInt();
+		setModified(true);
+		return true;
 	case kTheScrollTop:
 		_scroll = d.asInt();
+		setModified(true);
 		return true;
-	case kTheBorder:
-		_borderSize = d.asInt();
+	case kTheWordWrap:
+		warning("STUB: TextCastMember::getField(): wordWrap not implemented");
+		return false;
+	case kTheEditable:
+		_editable = d.asInt();
 		setModified(true);
 		return true;
 	case kTheButtonType:


Commit: 0005d43144a77279de55c397a137141b32eda156
    https://github.com/scummvm/scummvm/commit/0005d43144a77279de55c397a137141b32eda156
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: LINGO: Mark new event types

Changed paths:
    engines/director/lingo/lingo-events.cpp
    engines/director/types.h


diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index eed6ad8ff3c..29a4691410c 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -55,19 +55,20 @@ struct EventHandlerType {
 	{ kEventStepFrame,			"stepFrame"},
 	{ kEventExitFrame,			"exitFrame" },			//			D4
 
-	{ kEventActivateWindow,		"activateWindow" },
-	{ kEventDeactivateWindow,	"deactivateWindow" },
-	{ kEventMoveWindow,			"moveWindow" },
-	{ kEventResizeWindow,		"resizeWindow" },
-	{ kEventOpenWindow,			"openWindow" },
-	{ kEventCloseWindow,		"closeWindow" },
+	{ kEventActivateWindow,		"activateWindow" },		//				D5
+	{ kEventDeactivateWindow,	"deactivateWindow" },	//				D5
+	{ kEventMoveWindow,			"moveWindow" },			//				D5
+	{ kEventResizeWindow,		"resizeWindow" },		//				D5
+	{ kEventOpenWindow,			"openWindow" },			//				D5
+	{ kEventCloseWindow,		"closeWindow" },		//				D5
+	{ kEventZoomWindow,			"zoomWindow" },			//				D5
 
 	{ kEventKeyUp,				"keyUp" },				//			D4
 	{ kEventKeyDown,			"keyDown" },			// D2 w		D4 (as when from D2)
 	{ kEventMouseUp,			"mouseUp" },			// D2 w	D3
 	{ kEventMouseDown,			"mouseDown" },			// D2 w	D3
-	{ kEventRightMouseDown,		"rightMouseDown" },
-	{ kEventRightMouseUp,		"rightMouseUp" },
+	{ kEventRightMouseDown,		"rightMouseDown" },		//				D5
+	{ kEventRightMouseUp,		"rightMouseUp" },		//				D5
 	{ kEventMouseEnter,			"mouseEnter" },
 	{ kEventMouseLeave,			"mouseLeave" },
 	{ kEventMouseUpOutSide,		"mouseUpOutSide" },
diff --git a/engines/director/types.h b/engines/director/types.h
index ee0b2792313..c9573260188 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -218,8 +218,9 @@ enum LEvent {
 	kEventResizeWindow,
 	kEventOpenWindow,
 	kEventCloseWindow,
+	kEventZoomWindow,
 
-	kEventKeyUp, // 21
+	kEventKeyUp, // 22
 	kEventKeyDown,
 	kEventMouseUp,
 	kEventMouseDown,
@@ -230,9 +231,9 @@ enum LEvent {
 	kEventMouseUpOutSide,
 	kEventMouseWithin,
 
-	kEventStartUp, // 31
+	kEventStartUp, // 32
 
-	kEventMenuCallback // 32
+	kEventMenuCallback // 33
 };
 
 enum TransitionType {


Commit: c0df58acc81dd3aea341e89c7a08e7db8f2ee924
    https://github.com/scummvm/scummvm/commit/c0df58acc81dd3aea341e89c7a08e7db8f2ee924
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: XOBJ: Implement m_readPict in FileIO

Fixes display of text cards in Murphy's TV.

Changed paths:
    engines/director/castmember/bitmap.cpp
    engines/director/lingo/xlibs/fileio.cpp


diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 5d927b86aaf..7561f75f28f 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -840,6 +840,10 @@ bool BitmapCastMember::setField(int field, const Datum &d) {
 	case kThePicture:
 		if (d.type == PICTUREREF && d.u.picture != nullptr) {
 			setPicture(*d.u.picture);
+			// This is a random PICT from somewhere,
+			// set the external flag so we remap the palette.
+			_external = true;
+			_initialRect = Common::Rect(_picture->_surface.w, _picture->_surface.h);
 			return true;
 		} else {
 			warning("BitmapCastMember::setField(): Wrong Datum type %d for kThePicture (or nullptr)", d.type);
diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index 3e00eb30515..6cb7abae937 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -124,8 +124,11 @@ delete object me -- deletes the open file
 #include "common/file.h"
 #include "common/memstream.h"
 #include "common/savefile.h"
+#include "image/pict.h"
 
 #include "director/director.h"
+#include "director/picture.h"
+#include "director/types.h"
 #include "director/util.h"
 #include "director/lingo/lingo.h"
 #include "director/lingo/lingo-object.h"
@@ -450,7 +453,28 @@ void FileIO::m_readWord(int nargs) {
 	FileIO::m_readToken(2);
 }
 
-XOBJSTUB(FileIO::m_readPict, "")
+void FileIO::m_readPict(int nargs) {
+	FileObject *me = static_cast<FileObject *>(g_lingo->_state->me.u.obj);
+
+	Datum result;
+
+	if (!me->_inStream || me->_inStream->err()) {
+		g_lingo->push(result);
+		return;
+	}
+
+	me->_inStream->seek(0, SEEK_SET);
+
+	Image::PICTDecoder decoder;
+	if (decoder.loadStream(*me->_inStream)) {
+		result.type = PICTUREREF;
+		result.u.picture = new PictureReference;
+		result.u.picture->_picture = new Picture(decoder);
+	}
+
+	g_lingo->push(result);
+	return;
+}
 
 bool FileIO::charInMatchString(char ch, const Common::String &matchString) {
 	return matchString.contains(ch);


Commit: c4bd70d820fa6becb49c8dc98cf65804663ec9af
    https://github.com/scummvm/scummvm/commit/c4bd70d820fa6becb49c8dc98cf65804663ec9af
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Fix name remapping when duplicating a cast member

Fixes the language icons on the remote control in Murphy's TV.

Changed paths:
    engines/director/cast.cpp
    engines/director/cast.h
    engines/director/debugger.cpp
    engines/director/debugger/dt-score.cpp
    engines/director/frame.cpp
    engines/director/movie.cpp
    engines/director/score.cpp


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 5d7c0359f53..c4bd3cd7440 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -294,6 +294,9 @@ bool Cast::duplicateCastMember(CastMember *source, CastMemberInfo *info, int tar
 		_castsInfo[targetId] = newInfo;
 	}
 	setCastMember(targetId, target);
+	if (info) {
+		rebuildCastNameCache();
+	}
 	return true;
 }
 
@@ -342,7 +345,7 @@ bool Cast::loadConfig() {
 		return false;
 	}
 
-	debugC(1, kDebugLoading, "****** Loading Config VWCF");
+	debugC(1, kDebugLoading, "****** Loading Config VWCF for cast libID %d (%s)", _castLibID, _castName.c_str());
 
 	if (debugChannelSet(5, kDebugLoading))
 		stream->hexdump(stream->size());
@@ -564,6 +567,8 @@ void Cast::loadCast() {
 	// Font Directory
 	_vm->_wm->_fontMan->loadFonts(_castArchive->getPathName());
 
+	debugC(1, kDebugLoading, "****** Loading cast member data for for cast libID %d (%s)", _castLibID, _castName.c_str());
+
 	// CastMember Information Array
 	if (_castArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
 		_castIDoffset = _castArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'R'))[0];
@@ -636,18 +641,20 @@ void Cast::loadCast() {
 		_loadedCast = new Common::HashMap<int, CastMember *>();
 
 	if (cast.size() > 0) {
-		debugC(2, kDebugLoading, "****** Loading CASt resources for libId %d", _castLibID);
+		debugC(2, kDebugLoading, "****** Loading CASt resources for libId %d (%s), resourceId %d", _castLibID, _castName.c_str(), _libResourceId);
 
 		int idx = 0;
 
 		for (auto &iterator : cast) {
 			Resource res = _castArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), iterator);
-			debugC(2, kDebugLoading, "CASt: resource %d, castId %d, libResourceId %d", iterator, res.castId, res.libResourceId);
 			// Only load cast members which belong to the requested library ID.
 			// External casts only have one library ID, so instead
 			// we use the movie's mapping.
-			if (res.libResourceId != _libResourceId && !_isExternal)
+			if (res.libResourceId != _libResourceId && !_isExternal) {
+				debugC(5, kDebugLoading, "SKIPPED - CASt: resource %d, castId %d, libResourceId %d", iterator, res.castId, res.libResourceId);
 				continue;
+			}
+			debugC(2, kDebugLoading, "CASt: resource %d, castId %d, libResourceId %d", iterator, res.castId, res.libResourceId);
 			Common::SeekableReadStreamEndian *stream = _castArchive->getResource(MKTAG('C', 'A', 'S', 't'), iterator);
 			loadCastData(*stream, res.castId, &res);
 			delete stream;
diff --git a/engines/director/cast.h b/engines/director/cast.h
index ad79eeace73..ba91b1668de 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -91,6 +91,8 @@ public:
 	void setArchive(Archive *archive);
 	Archive *getArchive() const { return _castArchive; };
 	Common::String getMacName() const { return _macName; }
+	Common::String getCastName() const { return _castName; }
+	void setCastName(const Common::String &name) { _castName = name; }
 
 	bool loadConfig();
 	void loadCast();
@@ -185,6 +187,7 @@ private:
 	Common::Array<CastMember *> _loadQueue;
 
 	Common::String _macName;
+	Common::String _castName;
 
 	Common::HashMap<uint16, CastMemberInfo *> _castsInfo;
 	Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _castsNames;
diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 192c539fcb1..89e1716f784 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -362,7 +362,7 @@ bool Debugger::cmdCast(int argc, const char **argv) {
 		castId = atoi(argv[1]);
 
 	for (auto it : *movie->getCasts()) {
-		debugPrintf("Cast %d (%s):\n", it._key, it._value->getMacName().c_str());
+		debugPrintf("Cast %d (%s, %s):\n", it._key, it._value->getMacName().c_str(), it._value->getCastName().c_str());
 		Cast *cast = it._value;
 		if (!cast) {
 			debugPrintf("[empty]\n");
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index d11572ecd5b..b6d47adac1c 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -550,7 +550,7 @@ void showChannels() {
 			frame._mainChannels.transType, frame._mainChannels.transDuration, frame._mainChannels.transChunkSize);
 		ImGui::Text("SND: 1  sound1: %d, soundType1: %d", frame._mainChannels.sound1.member, frame._mainChannels.soundType1);
 		ImGui::Text("SND: 2  sound2: %d, soundType2: %d", frame._mainChannels.sound2.member, frame._mainChannels.soundType2);
-		ImGui::Text("LSCR:   actionId: %d", frame._mainChannels.actionId.member);
+		ImGui::Text("LSCR:   actionId: %s", frame._mainChannels.actionId.asString().c_str());
 
 		if (ImGui::BeginTable("Channels", 21, ImGuiTableFlags_Borders)) {
 			ImGuiTableFlags flags = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_AngledHeader;
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index f9a77b8a4dc..75c6171fbc0 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -1247,7 +1247,7 @@ Common::String Frame::formatChannelInfo() {
 		_mainChannels.transType, _mainChannels.transDuration, _mainChannels.transChunkSize);
 	result += Common::String::format("SND: 1  sound1: %d, soundType1: %d\n", _mainChannels.sound1.member, _mainChannels.soundType1);
 	result += Common::String::format("SND: 2  sound2: %d, soundType2: %d\n", _mainChannels.sound2.member, _mainChannels.soundType2);
-	result += Common::String::format("LSCR:   actionId: %d\n", _mainChannels.actionId.member);
+	result += Common::String::format("LSCR:   actionId: %s\n", _mainChannels.actionId.asString().c_str());
 
 	for (int i = 0; i < _numChannels; i++) {
 		Sprite &sprite = *_sprites[i + 1];
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index adc17735151..afac709ed4a 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -181,6 +181,7 @@ void Movie::loadCastLibMapping(Common::SeekableReadStreamEndian &stream) {
 			cast = _casts.getVal(libId);
 		} else {
 			cast = new Cast(this, libId, false, isExternal, libResourceId);
+			cast->setCastName(name);
 			_casts.setVal(libId, cast);
 		}
 		_castNames[name] = libId;
@@ -488,6 +489,9 @@ bool Movie::duplicateCastMember(CastMemberID source, CastMemberID target) {
 		warning("Movie::duplicateCastMember(): couldn't find source cast member %s", source.asString().c_str());
 	} else if (!targetCast) {
 		warning("Movie::duplicateCastMember(): couldn't find destination castLib %d", target.castLib);
+	} else if (source == target) {
+		warning("Movie::duplicateCastMember(): trying to duplicate cast member %s over itself", source.asString().c_str());
+		return false;
 	} else {
 		CastMember *sourceMember = sourceCast->getCastMember(source.member);
 		CastMemberInfo *sourceInfo = sourceCast->getCastMemberInfo(source.member);
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 5b1e9a70cc7..a50e298e692 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1916,7 +1916,7 @@ Common::String Score::formatChannelInfo() {
 		frame._mainChannels.transType, frame._mainChannels.transDuration, frame._mainChannels.transChunkSize);
 	result += Common::String::format("SND: 1  sound1: %d, soundType1: %d\n", frame._mainChannels.sound1.member, frame._mainChannels.soundType1);
 	result += Common::String::format("SND: 2  sound2: %d, soundType2: %d\n", frame._mainChannels.sound2.member, frame._mainChannels.soundType2);
-	result += Common::String::format("LSCR:   actionId: %d\n", frame._mainChannels.actionId.member);
+	result += Common::String::format("LSCR:   actionId: %s\n", frame._mainChannels.actionId.asString().c_str());
 
 	for (int i = 0; i < frame._numChannels; i++) {
 		Channel &channel = *_channels[i + 1];


Commit: 2d58f99fd6387b1b8f19e2acfa216122ea915b5b
    https://github.com/scummvm/scummvm/commit/2d58f99fd6387b1b8f19e2acfa216122ea915b5b
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Overhaul TextCastMember

Include new properties/aliases introduced in D5, fixes crashes related
to incorrect casting to MacText.

Changed paths:
    engines/director/castmember/text.cpp
    engines/director/castmember/text.h
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h
    graphics/macgui/macfontmanager.cpp
    graphics/macgui/macfontmanager.h
    graphics/macgui/mactext.cpp
    graphics/macgui/mactext.h
    graphics/macgui/mactextwindow.h


diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index 27f5b82798c..7e99a40d725 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -209,10 +209,16 @@ void TextCastMember::setColors(uint32 *fgcolor, uint32 *bgcolor) {
 		_bgcolor = *bgcolor;
 
 	// if we want to keep the format unchanged, then we need to modify _ftext as well
-	if (_widget)
-		((Graphics::MacText *)_widget)->setColors(_fgcolor, _bgcolor);
-	else
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			((Graphics::MacTextWindow *)target)->setColors(_fgcolor, _bgcolor);
+		} else {
+			((Graphics::MacText *)target)->setColors(_fgcolor, _bgcolor);
+		}
+	} else {
 		_modified = true;
+	}
 }
 
 Graphics::TextAlign TextCastMember::getAlignment() {
@@ -232,11 +238,36 @@ void TextCastMember::setBackColor(uint32 bgCol) {
 	_modified = true;
 }
 
+uint32 TextCastMember::getForeColor(int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->getTextColor(start, end);
+		} else {
+			return ((Graphics::MacText *)target)->getTextColor(start, end);
+		}
+	}
+	return _fgcolor;
+}
+
 void TextCastMember::setForeColor(uint32 fgCol) {
 	_fgcolor = fgCol;
 	_modified = true;
 }
 
+void TextCastMember::setForeColor(uint32 fgCol, int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->setTextColor(fgCol, start, end);
+		} else {
+			return ((Graphics::MacText *)target)->setTextColor(fgCol, start, end);
+		}
+	}
+	_modified = true;
+}
+
+
 void TextCastMember::importStxt(const Stxt *stxt) {
 	_fontId = stxt->_style.fontId;
 	_textSlant = stxt->_style.textSlant;
@@ -354,6 +385,30 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
 	return widget;
 }
 
+Graphics::MacWidget *TextCastMember::getWidget() {
+	// FIXME: The cast member should be the source of truth for the widget.
+	// You don't have the issue you have with e.g. bitmaps where the channel
+	// can stretch: all sprites of the cast member have the same dimensions.
+	// There is technically a small window between typing something in and hitting
+	// enter/defocusing where other copies of the widget are out of sync,
+	// but they will resync pretty quickly.
+	Channel *toEdit = nullptr;
+	Common::Array<Channel *> channels = g_director->getCurrentMovie()->getScore()->_channels;
+	for (uint i = 0; i < channels.size(); i++) {
+		if (channels[i]->_sprite->_cast == this) {
+			toEdit = channels[i];
+			break;
+		}
+	}
+	if (toEdit) {
+		Common::Rect bbox = toEdit->getBbox();
+		if (!toEdit->_widget)
+			toEdit->_widget = createWidget(bbox, toEdit, toEdit->_sprite->_spriteType);
+		return toEdit->_widget;
+	}
+	return _widget;
+}
+
 void TextCastMember::importRTE(byte *text) {
 	//assert(rteList.size() == 3);
 	//child0 is probably font data.
@@ -376,22 +431,88 @@ void TextCastMember::setRawText(const Common::String &text) {
 	_modified = true;
 }
 
+int TextCastMember::getLineCount() {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->getRowCount();
+		} else {
+			return ((Graphics::MacText *)target)->getRowCount();
+		}
+	}
+	warning("TextCastMember::getLineCount(): no widget available, returning 0");
+	return 0;
+}
+
 // D4 dictionary book said this is line spacing
 int TextCastMember::getTextHeight() {
-	if (_widget)
-		return ((Graphics::MacText *)_widget)->getLineSpacing();
-	else
-		return _lineSpacing;
-	return 0;
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->getLineSpacing();
+		} else {
+			return ((Graphics::MacText *)target)->getLineSpacing();
+		}
+	}
+	return _lineSpacing;
 }
 
-// this should be amend when we have some where using this function
-int TextCastMember::getTextSize() {
-	if (_widget)
-		return ((Graphics::MacText *)_widget)->getTextSize();
-	else
-		return _fontSize;
-	return 0;
+Common::String TextCastMember::getTextFont() {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			int fontId = ((Graphics::MacTextWindow *)target)->getTextFont();
+			return g_director->_wm->_fontMan->getFontName(fontId);
+		} else {
+			int fontId = ((Graphics::MacText *)target)->getTextFont();
+			return g_director->_wm->_fontMan->getFontName(fontId);
+		}
+	}
+	return g_director->_wm->_fontMan->getFontName(_fontId);
+}
+
+Common::String TextCastMember::getTextFont(int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			int fontId = ((Graphics::MacTextWindow *)target)->getTextFont(start, end);
+			return g_director->_wm->_fontMan->getFontName(fontId);
+		} else {
+			int fontId = ((Graphics::MacText *)target)->getTextFont(start, end);
+			return g_director->_wm->_fontMan->getFontName(fontId);
+		}
+	}
+	return g_director->_wm->_fontMan->getFontName(_fontId);
+}
+
+void TextCastMember::setTextFont(const Common::String &fontName) {
+	Graphics::MacWidget *target = getWidget();
+	if (!target)
+		return;
+	if (_textType == kTextTypeScrolling) {
+		((Graphics::MacTextWindow *)target)->enforceTextFont((uint16) g_director->_wm->_fontMan->getFontIdByName(fontName));
+		_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+		_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+	} else {
+		((Graphics::MacText *)target)->enforceTextFont((uint16) g_director->_wm->_fontMan->getFontIdByName(fontName));
+		_ptext = ((Graphics::MacText *)target)->getPlainText();
+		_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+	}
+}
+
+void TextCastMember::setTextFont(const Common::String &fontName, int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (!target)
+		return;
+	if (_textType == kTextTypeScrolling) {
+		((Graphics::MacTextWindow *)target)->setTextFont((uint16) g_director->_wm->_fontMan->getFontIdByName(fontName), start, end);
+		_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+		_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+	} else {
+		((Graphics::MacText *)target)->setTextFont((uint16) g_director->_wm->_fontMan->getFontIdByName(fontName), start, end);
+		_ptext = ((Graphics::MacText *)target)->getPlainText();
+		_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+	}
 }
 
 Common::U32String TextCastMember::getText() {
@@ -402,19 +523,136 @@ Common::String TextCastMember::getRawText() {
 	return _rtext;
 }
 
+int TextCastMember::getTextSize() {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->getTextSize();
+		} else {
+			return ((Graphics::MacText *)target)->getTextSize();
+		}
+	}
+
+	return _fontSize;
+}
+
+int TextCastMember::getTextSize(int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			return ((Graphics::MacTextWindow *)target)->getTextSize(start, end);
+		} else {
+			return ((Graphics::MacText *)target)->getTextSize(start, end);
+		}
+	}
+
+	return _fontSize;
+}
+
 void TextCastMember::setTextSize(int textSize) {
-	if (_widget) {
-		((Graphics::MacText *)_widget)->setTextSize(textSize);
-		((Graphics::MacText *)_widget)->draw();
-	} else {
-		_fontSize = textSize;
-		_modified = true;
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			((Graphics::MacTextWindow *)target)->setTextSize(textSize);
+			_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+			_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+		} else {
+			((Graphics::MacText *)target)->setTextSize(textSize);
+			_ptext = ((Graphics::MacText *)target)->getPlainText();
+			_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+			((Graphics::MacText *)target)->draw();
+		}
 	}
+	_fontSize = textSize;
+	_modified = true;
+}
+
+void TextCastMember::setTextSize(int textSize, int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			((Graphics::MacTextWindow *)target)->setTextSize(textSize, start, end);
+			_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+			_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+		} else {
+			((Graphics::MacText *)target)->setTextSize(textSize, start, end);
+			_ptext = ((Graphics::MacText *)target)->getPlainText();
+			_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+			((Graphics::MacText *)target)->draw();
+		}
+	}
+	_modified = true;
+}
+
+Common::String TextCastMember::getTextStyle() {
+	int slantVal = _textSlant;
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			slantVal = ((Graphics::MacTextWindow *)target)->getTextSlant();
+		} else {
+			slantVal = ((Graphics::MacText *)target)->getTextSlant();
+		}
+	}
+	return g_director->_wm->_fontMan->getNameFromSlant(slantVal);
+}
+
+Common::String TextCastMember::getTextStyle(int start, int end) {
+	int slantVal = _textSlant;
+	Graphics::MacWidget *target = getWidget();
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			slantVal = ((Graphics::MacTextWindow *)target)->getTextSlant(start, end);
+		} else {
+			slantVal = ((Graphics::MacText *)target)->getTextSlant(start, end);
+		}
+	}
+	return g_director->_wm->_fontMan->getNameFromSlant(slantVal);
+}
+
+void TextCastMember::setTextStyle(const Common::String &textStyle) {
+	Graphics::MacWidget *target = getWidget();
+	int slant = g_director->_wm->_fontMan->parseSlantFromName(textStyle);
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			((Graphics::MacTextWindow *)target)->enforceTextSlant(slant);
+			_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+			_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+		} else {
+			((Graphics::MacText *)target)->enforceTextSlant(slant);
+			_ptext = ((Graphics::MacText *)target)->getPlainText();
+			_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+			((Graphics::MacText *)target)->draw();
+		}
+	}
+	_modified = true;
+}
+
+void TextCastMember::setTextStyle(const Common::String &textStyle, int start, int end) {
+	Graphics::MacWidget *target = getWidget();
+	int slant = g_director->_wm->_fontMan->parseSlantFromName(textStyle);
+	if (target) {
+		if (_textType == kTextTypeScrolling) {
+			((Graphics::MacTextWindow *)target)->setTextSlant(slant, start, end);
+			_ptext = ((Graphics::MacTextWindow *)target)->getPlainText();
+			_ftext = ((Graphics::MacTextWindow *)target)->getTextChunk(0, 0, -1, -1, true);
+		} else {
+			((Graphics::MacText *)target)->setTextSlant(slant, start, end);
+			_ptext = ((Graphics::MacText *)target)->getPlainText();
+			_ftext = ((Graphics::MacText *)target)->getTextChunk(0, 0, -1, -1, true);
+			((Graphics::MacText *)target)->draw();
+		}
+	}
+	_modified = true;
 }
 
 void TextCastMember::updateFromWidget(Graphics::MacWidget *widget) {
 	if (widget && _type == kCastText) {
-		_ptext = ((Graphics::MacText *)widget)->getEditedString();
+		if (_textType == kTextTypeScrolling) {
+			_ptext = ((Graphics::MacTextWindow *)widget)->getEditedString();
+		} else {
+			_ptext = ((Graphics::MacText *)widget)->getEditedString();
+		}
 	}
 }
 
@@ -479,10 +717,16 @@ bool TextCastMember::hasField(int field) {
 	case kTheTextSize:
 	case kTheTextStyle:
 		return true;
+	case kTheAutoTab:
 	case kTheBorder:
+	case kTheBoxDropShadow:
+	case kTheBoxType:
+	case kTheEditable:
+	case kTheLineCount:
+	case kTheMargin:
+	case kThePageHeight:
 	case kTheScrollTop:
 	case kTheWordWrap:
-	case kTheEditable:
 		return _type == kCastText;
 	case kTheButtonType:
 		return _type == kCastButton;
@@ -520,8 +764,7 @@ Datum TextCastMember::getField(int field) {
 		}
 		break;
 	case kTheTextFont:
-		d.type = STRING;
-		d.u.s = new Common::String(g_director->_wm->_fontMan->getFontName(_fontId));
+		d = getTextFont();
 		break;
 	case kTheTextHeight:
 		d = getTextHeight();
@@ -530,11 +773,33 @@ Datum TextCastMember::getField(int field) {
 		d = getTextSize();
 		break;
 	case kTheTextStyle:
-		d = (int)_textSlant;
+		d = getTextStyle();
+		break;
+	case kTheAutoTab:
+		warning("STUB: TextCastMember::getField(): autoTab not implemented");
+		d = 1;
 		break;
 	case kTheBorder:
 		d = _borderSize;
 		break;
+	case kTheBoxDropShadow:
+		warning("STUB: TextCastMember::getField(): boxDropShadow not implemented");
+		d = 1;
+		break;
+	case kTheEditable:
+		d = (int)_editable;
+		break;
+	case kTheLineCount:
+		d = getLineCount();
+		break;
+	case kTheMargin:
+		warning("STUB: TextCastMember::getField(): margin not implemented");
+		d = 0;
+		break;
+	case kThePageHeight:
+		warning("STUB: TextCastMember::getField(): pageHeight not implemented");
+		d = 0;
+		break;
 	case kTheScrollTop:
 		d = _scroll;
 		break;
@@ -542,9 +807,6 @@ Datum TextCastMember::getField(int field) {
 		warning("STUB: TextCastMember::getField(): wordWrap not implemented");
 		d = 1;
 		break;
-	case kTheEditable:
-		d = (int)_editable;
-		break;
 	case kTheButtonType:
 		switch (_buttonType) {
 		case kTypeCheckBox:
@@ -570,23 +832,6 @@ Datum TextCastMember::getField(int field) {
 }
 
 bool TextCastMember::setField(int field, const Datum &d) {
-	Channel *toEdit = nullptr;
-
-	if (field == kTheTextFont || field == kTheTextSize || field == kTheTextStyle) {
-		Common::Array<Channel *> channels = g_director->getCurrentMovie()->getScore()->_channels;
-		for (uint i = 0; i < channels.size(); i++) {
-			if (channels[i]->_sprite->_cast == this) {
-				toEdit = channels[i];
-				break;
-			}
-		}
-		if (toEdit) {
-			Common::Rect bbox = toEdit->getBbox();
-			if (!toEdit->_widget)
-				toEdit->_widget = createWidget(bbox, toEdit, toEdit->_sprite->_spriteType);
-		}
-	}
-
 	switch (field) {
 	case kTheBackColor:
 		{
@@ -606,21 +851,18 @@ bool TextCastMember::setField(int field, const Datum &d) {
 		_hilite = (bool)d.asInt();
 		_modified = true;
 		return true;
-		break;
 	case kTheText:
 		setRawText(d.asString());
 		return true;
 	case kTheTextAlign:
 		{
-			Common::String select = d.asString(true);
-			select.toLowercase();
-
+			Common::String select = d.asString();
 			TextAlignType align;
-			if (select == "\"left\"") {
+			if (select.equalsIgnoreCase("left")) {
 				align = kTextAlignLeft;
-			} else if (select == "\"center\"") {
+			} else if (select.equalsIgnoreCase("center")) {
 				align = kTextAlignCenter;
-			} else if (select == "\"right\"") {
+			} else if (select.equalsIgnoreCase("right")) {
 				align = kTextAlignRight;
 			} else {
 				warning("TextCastMember::setField(): Unknown text align spec: %s", d.asString(true).c_str());
@@ -629,57 +871,54 @@ bool TextCastMember::setField(int field, const Datum &d) {
 
 			_textAlign = align;
 			_modified = true;
-	}
+		}
 		return true;
 	case kTheTextFont:
-		if (!toEdit) {
-			warning("Channel containing this CastMember %d doesn't exist", (int) _castId);
-			return false;
-		}
-		((Graphics::MacText *)toEdit->_widget)->enforceTextFont((uint16) g_director->_wm->_fontMan->getFontIdByName(d.asString()));
-		_ptext = ((Graphics::MacText *)toEdit->_widget)->getPlainText();
-		_ftext = ((Graphics::MacText *)toEdit->_widget)->getTextChunk(0, 0, -1, -1, true);
+		setTextFont(d.asString());
 		return true;
 	case kTheTextHeight:
 		_lineSpacing = d.asInt();
 		_modified = true;
 		return false;
 	case kTheTextSize:
-		if (!toEdit) {
-			warning("Channel containing this CastMember %d doesn't exist", (int) _castId);
-			return false;
-		}
-		((Graphics::MacText *)toEdit->_widget)->setTextSize(d.asInt());
-		_ptext = ((Graphics::MacText *)toEdit->_widget)->getPlainText();
-		_ftext = ((Graphics::MacText *)toEdit->_widget)->getTextChunk(0, 0, -1, -1, true);
+		setTextSize(d.asInt());
 		return true;
 	case kTheTextStyle:
-		if (!toEdit) {
-			warning("Channel containing this CastMember %d doesn't exist", (int) _castId);
-			return false;
-		}
-		{
-			int slant = g_director->_wm->_fontMan->parseSlantFromName(d.asString());
-			((Graphics::MacText *)toEdit->_widget)->enforceTextSlant(slant);
-		}
-		_ptext = ((Graphics::MacText *)toEdit->_widget)->getPlainText();
-		_ftext = ((Graphics::MacText *)toEdit->_widget)->getTextChunk(0, 0, -1, -1, true);
+		setTextStyle(d.asString());
 		return true;
+	case kTheAutoTab:
+		warning("STUB: TextCastMember::setField(): autoTab not implemented");
+		return false;
 	case kTheBorder:
 		_borderSize = d.asInt();
 		setModified(true);
 		return true;
+	case kTheBoxDropShadow:
+		warning("STUB: TextCastMember::setField(): boxDropShadow not implemented");
+		return false;
+	case kTheBoxType:
+		warning("STUB: TextCastMember::setField(): boxType not implemented");
+		return false;
+	case kTheEditable:
+		_editable = d.asInt();
+		setModified(true);
+		return true;
+	case kTheLineCount:
+		warning("BUILDBOT: TextCastMember::setField(): Attempt to set read-only field %s of cast %d", g_lingo->entity2str(field), _castId);
+		return false;
+	case kTheMargin:
+		warning("STUB: TextCastMember::setField(): margin not implemented");
+		return false;
+	case kThePageHeight:
+		warning("BUILDBOT: TextCastMember::setField(): Attempt to set read-only field %s of cast %d", g_lingo->entity2str(field), _castId);
+		return false;
 	case kTheScrollTop:
 		_scroll = d.asInt();
 		setModified(true);
 		return true;
 	case kTheWordWrap:
-		warning("STUB: TextCastMember::getField(): wordWrap not implemented");
+		warning("STUB: TextCastMember::setField(): wordWrap not implemented");
 		return false;
-	case kTheEditable:
-		_editable = d.asInt();
-		setModified(true);
-		return true;
 	case kTheButtonType:
 		if (d.type == SYMBOL) {
 			if (d.u.s->equalsIgnoreCase("pushButton")) {
@@ -705,6 +944,13 @@ bool TextCastMember::setField(int field, const Datum &d) {
 	return CastMember::setField(field, d);
 }
 
+// This isn't documented particularly well by the Lingo Dictionary;
+// as well as letting you read/write properties on the cast member,
+// Director allows you to read/write some properties to a subset of the text
+// within the cast member defined by a chunk expression, e.g.:
+//
+// set the textStyle of char 2 to 4 of field "Pudge" to "bold"
+
 bool TextCastMember::hasChunkField(int field) {
 	switch (field) {
 	case kTheForeColor:
@@ -722,43 +968,22 @@ bool TextCastMember::hasChunkField(int field) {
 Datum TextCastMember::getChunkField(int field, int start, int end) {
 	Datum d;
 
-	Graphics::MacText *macText = ((Graphics::MacText *)_widget);
-	if (!_widget)
-		warning("TextCastMember::getChunkField getting chunk field when there is no linked widget, returning the default value");
-
 	switch (field) {
 	case kTheForeColor:
-		if (_widget)
-			d.u.i = macText->getTextColor(start, end);
-		else
-			d.u.i = getForeColor();
+		d = (int)getForeColor(start, end);
 		break;
-	case kTheTextFont: {
-		int fontId;
-		if (_widget)
-			fontId = macText->getTextFont(start, end);
-		else
-			fontId = _fontId;
-
-		d.type = STRING;
-		d.u.s = new Common::String(g_director->_wm->_fontMan->getFontName(fontId));
+	case kTheTextFont:
+		d = getTextFont(start, end);
 		break;
-		}
 	case kTheTextHeight:
-		warning("TextCastMember::getChunkField getting text height(line spacing) is not implemented yet, returning the default one");
-		d.u.i = _lineSpacing;
+		warning("TextCastMember::getChunkField(): getting text height(line spacing) is not implemented yet, returning the default one");
+		d = (int)_lineSpacing;
 		break;
 	case kTheTextSize:
-		if (_widget)
-			d.u.i = macText->getTextSize(start, end);
-		else
-			d.u.i = _fontSize;
+		d = getTextSize(start, end);
 		break;
 	case kTheTextStyle:
-		if (_widget)
-			d.u.i = macText->getTextSlant(start, end);
-		else
-			d.u.i = _textSlant;
+		d = getTextStyle(start, end);
 		break;
 	default:
 		break;
@@ -768,29 +993,22 @@ Datum TextCastMember::getChunkField(int field, int start, int end) {
 }
 
 bool TextCastMember::setChunkField(int field, int start, int end, const Datum &d) {
-	Graphics::MacText *macText = ((Graphics::MacText *)_widget);
-	if (!_widget)
-		warning("TextCastMember::setChunkField setting chunk field when there is no linked widget");
 
 	switch (field) {
 	case kTheForeColor:
-		if (_widget)
-			macText->setTextColor(d.asInt(), start, end);
+		setForeColor(d.asInt(), start, end);
 		return true;
 	case kTheTextFont:
-		if (_widget)
-			macText->setTextFont(d.asInt(), start, end);
+		setTextFont(d.asString(), start, end);
 		return true;
 	case kTheTextHeight:
-		warning("TextCastMember::setChunkField setting text height(line spacing) is not implemented yet");
+		warning("TextCastMember::setChunkField(): setting text height(line spacing) is not implemented yet");
 		return false;
 	case kTheTextSize:
-		if (_widget)
-			macText->setTextSize(d.asInt(), start, end);
+		setTextSize(d.asInt(), start, end);
 		return true;
 	case kTheTextStyle:
-		if (_widget)
-			macText->setTextSlant(d.asInt(), start, end);
+		setTextStyle(d.asString(), start, end);
 		return true;
 	default:
 		break;
diff --git a/engines/director/castmember/text.h b/engines/director/castmember/text.h
index fdac20b5ae0..477eea794fc 100644
--- a/engines/director/castmember/text.h
+++ b/engines/director/castmember/text.h
@@ -34,6 +34,8 @@ public:
 
 	Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
 
+	Graphics::MacWidget *getWidget();
+
 	bool isEditable() override { return _editable; }
 	void setEditable(bool editable) override { _editable = editable; }
 	void updateFromWidget(Graphics::MacWidget *widget) override;
@@ -42,7 +44,9 @@ public:
 	uint32 getBackColor() override { return _bgcolor; }
 	void setBackColor(uint32 bgCol) override;
 	uint32 getForeColor() override { return _fgcolor; }
+	uint32 getForeColor(int start, int end);
 	void setForeColor(uint32 fgCol) override;
+	void setForeColor(uint32 fgCol, int start, int end);
 
 	bool hasField(int field) override;
 	Datum getField(int field) override;
@@ -52,10 +56,24 @@ public:
 	Datum getChunkField(int field, int start, int end);
 	bool setChunkField(int field, int start, int end, const Datum &value);
 
+	int getLineCount();
+
 	int getTextHeight();
 
+	Common::String getTextFont();
+	Common::String getTextFont(int start, int end);
+	void setTextFont(const Common::String &fontName);
+	void setTextFont(const Common::String &fontName, int start, int end);
+
 	int getTextSize();
+	int getTextSize(int start, int end);
 	void setTextSize(int textSize);
+	void setTextSize(int textSize, int start, int end);
+
+	Common::String getTextStyle();
+	Common::String getTextStyle(int start, int end);
+	void setTextStyle(const Common::String &textStyle);
+	void setTextStyle(const Common::String &textStyle, int start, int end);
 
 	Common::String formatInfo() override;
 
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 51da8e1cfe9..e6e410f3f7f 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -227,7 +227,6 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"castLibNum",	kTheCastLibNum,	500 },// 					D5 p
 	{ kTheCast,		"castType",		kTheCastType,	400 },//				D4 p
 	{ kTheCast,		"filename",		kTheFileName,	400 },//				D4 p
-	{ kTheCast,		"editable",		kTheEditable,	500 },//					D5 p
 	{ kTheCast,		"foreColor",	kTheForeColor,	400 },//				D4 p
 	{ kTheCast,		"height",		kTheHeight,		400 },//				D4 p
 	{ kTheCast,		"idleReadChunkSize",kTheIdleReadChunkSize,500 },//			D5 p
@@ -237,7 +236,6 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"modified",		kTheModified,	400 },//				D4 p
 	{ kTheCast,		"name",			kTheName,		300 },//		D3 p
 	{ kTheCast,		"number",		kTheNumber,		300 },//		D3 p
-	{ kTheCast,		"pageHeight",	kThePageHeight,	500 },//					D5 p
 	{ kTheCast,		"rect",			kTheRect,		400 },//				D4 p
 	{ kTheCast,		"purgePriority",kThePurgePriority,400 },//				D4 p // 0 Never purge, 1 Purge Last, 2 Purge next, 2 Purge normal
 	{ kTheCast,		"scriptText",	kTheScriptText,	400 },//				D4 p
@@ -285,7 +283,21 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"picture",		kThePicture,	300 },//		D3 p
 
 	// TextCastMember fields
+	{ kTheCast,		"alignment",	kTheTextAlign,	500 },//						D5 p
+	{ kTheCast,		"autoTab",		kTheAutoTab,	500 },//						D5 p
+	{ kTheCast,		"border",		kTheBorder,		500 },//						D5 p
+	{ kTheCast,		"boxDropShadow",kTheBoxDropShadow,	500 },//					D5 p
+	{ kTheCast,		"boxType",		kTheBoxType,	500 },//						D5 p
+	{ kTheCast,		"dropShadow",	kTheDropShadow,	500 },//						D5 p
+	{ kTheCast,		"editable",		kTheEditable,	500 },//						D5 p
+	{ kTheCast,		"font",			kTheTextFont,	500 },//						D5 p
+	{ kTheCast,		"fontSize",		kTheTextSize,	500 },//						D5 p
+	{ kTheCast,		"fontStyle",	kTheTextStyle,	500 },//						D5 p
+	{ kTheCast,		"lineCount",	kTheLineCount,	500 },//						D5 p
+	{ kTheCast,		"lineHeight",	kTheTextHeight,	500 },//						D5 p
 	{ kTheCast,		"hilite",		kTheHilite,		200 },// D2 p
+	{ kTheCast,		"margin",		kTheMargin,		500 },//						D5 p
+	{ kTheCast,		"pageHeight",	kThePageHeight,	500 },//						D5 p
 	{ kTheCast,		"text",			kTheText,		200 },// D2 p
 	{ kTheCast,		"textAlign",	kTheTextAlign,	300 },//		D3 p
 	{ kTheCast,		"textFont",		kTheTextFont,	300 },//		D3 p
@@ -293,6 +305,7 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"textSize",		kTheTextSize,	300 },//		D3 p
 	{ kTheCast,		"textStyle",	kTheTextStyle,	300 },//		D3 p
 	{ kTheCast,		"scrollTop",	kTheScrollTop,  500 },//						D5 p
+	{ kTheCast,		"wordWrap",		kTheWordWrap,	500 },//						D5 p
 
 	// ButtonCastMember fields
 	{ kTheCast,		"buttonType",	kTheButtonType,	500 },//						D5 p
@@ -307,14 +320,13 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"transitionType",kTheTransitionType,500 },//					D5 p
 
 	// Field fields
-	{ kTheField,	"autoTab",		kTheAutoTab,	500 },//						D5 p
-	{ kTheField,	"border",		kTheBorder,		500 },//						D5 p
-	{ kTheField,	"boxType",		kTheBoxType,	500 },//						D5 p
-	{ kTheField,	"dropShadow",	kTheDropShadow,	500 },//						D5 p
+	{ kTheField,	"alignment",	kTheTextAlign,	500 },//						D5 p
+	{ kTheField,	"font",			kTheTextFont,	500 },//						D5 p
+	{ kTheField,	"fontSize",		kTheTextSize,	500 },//						D5 p
+	{ kTheField,	"fontStyle",	kTheTextStyle,	500 },//						D5 p
 	{ kTheField,	"foreColor",	kTheForeColor,	400 },//				D4 p
 	{ kTheField,	"hilite",		kTheHilite,		200 },// D2 p
-	{ kTheField,	"lineCount",	kTheLineCount,	500 },//						D5 p
-	{ kTheField,	"margin",		kTheMargin,		500 },//						D5 p
+	{ kTheField,	"lineHeight",	kTheTextHeight,	500 },//						D5 p
 	{ kTheField,	"name",			kTheName,		300 },//		D3 p
 	{ kTheField,	"text",			kTheText,		200 },// D2 p
 	{ kTheField,	"textAlign",	kTheTextAlign,	300 },//		D3 p
@@ -322,11 +334,13 @@ const TheEntityField fields[] = {
 	{ kTheField,	"textHeight",	kTheTextHeight,	300 },//		D3 p
 	{ kTheField,	"textSize",		kTheTextSize,	300 },//		D3 p
 	{ kTheField,	"textStyle",	kTheTextStyle,	300 },//		D3 p
-	{ kTheField,	"scrollTop",	kTheScrollTop,  500 },//						D5 p
-	{ kTheField,	"wordWrap",		kTheWordWrap,	500 },//						D5 p
 
 	// Chunk fields
+	{ kTheChunk,	"font",			kTheTextFont,	500 },//						D5 p
+	{ kTheChunk,	"fontSize",		kTheTextSize,	500 },//						D5 p
+	{ kTheChunk,	"fontStyle",	kTheTextStyle,	500 },//						D5 p
 	{ kTheChunk,	"foreColor",	kTheForeColor,	400 },//				D4 p
+	{ kTheChunk,	"lineHeight",	kTheTextHeight,	500 },//						D5 p
 	{ kTheChunk,	"textFont",		kTheTextFont,	300 },//		D3 p
 	{ kTheChunk,	"textHeight",	kTheTextHeight,	300 },//		D3 p
 	{ kTheChunk,	"textSize",		kTheTextSize,	300 },//		D3 p
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index c8d58be9961..30e0287fc25 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -176,6 +176,7 @@ enum TheFieldType {
 	kTheBlend,
 	kTheBorder,
 	kTheBottom,
+	kTheBoxDropShadow,
 	kTheBoxType,
 	kTheButtonType,
 	kTheCastLibNum,
diff --git a/graphics/macgui/macfontmanager.cpp b/graphics/macgui/macfontmanager.cpp
index baadbd3fa2f..b0c101c8057 100644
--- a/graphics/macgui/macfontmanager.cpp
+++ b/graphics/macgui/macfontmanager.cpp
@@ -22,6 +22,7 @@
 #include "common/stream.h"
 #include "common/compression/unzip.h"
 #include "common/macresman.h"
+#include "common/tokenizer.h"
 #include "graphics/fonts/bdf.h"
 #include "graphics/fonts/macfont.h"
 #include "graphics/fonts/winfont.h"
@@ -617,28 +618,64 @@ int MacFontManager::parseFontSlant(Common::String slant) {
 }
 
 int MacFontManager::parseSlantFromName(const Common::String &name) {
-	int slantVal = 0;
+	int slantVal = kMacFontRegular; // 0
+
+	Common::StringArray tokens = Common::StringTokenizer(name, " ,").split();
+	while (tokens.size()) {
+		Common::String subName = tokens.back();
+		tokens.pop_back();
+		if (subName.equalsIgnoreCase("bold"))
+			slantVal |= kMacFontBold;
+		if (subName.equalsIgnoreCase("italic"))
+			slantVal |= kMacFontItalic;
+		if (subName.equalsIgnoreCase("underline"))
+			slantVal |= kMacFontUnderline;
+		if (subName.equalsIgnoreCase("shadow"))
+			slantVal |= kMacFontShadow;
+		if (subName.equalsIgnoreCase("outline"))
+			slantVal |= kMacFontOutline;
+		if (subName.equalsIgnoreCase("condense"))
+			slantVal |= kMacFontCondense;
+		if (subName.equalsIgnoreCase("extend"))
+			slantVal |= kMacFontExtend;
+		// If plain is specified at any point, zero out the flags
+		if (subName.equalsIgnoreCase("plain"))
+			slantVal = kMacFontRegular;
+	}
+	return slantVal;
+}
 
-	if (name.contains(" Bold") || name.equalsIgnoreCase("Bold"))
-		slantVal |= kMacFontBold;
-	if (name.contains(" Italic") || name.equalsIgnoreCase("Italic"))
-		slantVal |= kMacFontItalic;
-	if (name.contains(" Regular") || name.equalsIgnoreCase("Regular"))
-		slantVal |= kMacFontRegular;
-	if (name.contains(" Underline") || name.equalsIgnoreCase("Underline"))
-		slantVal |= kMacFontUnderline;
-	if (name.contains(" Shadow") || name.equalsIgnoreCase("Shadow"))
-		slantVal |= kMacFontShadow;
-	if (name.contains(" Outline") || name.equalsIgnoreCase("Outline"))
-		slantVal |= kMacFontOutline;
-	if (name.contains(" Condense") || name.equalsIgnoreCase("Condense"))
-		slantVal |= kMacFontCondense;
-	if (name.contains(" Extend") || name.equalsIgnoreCase("Extend"))
-		slantVal |= kMacFontExtend;
-	if (name.contains(" Plain") || name.equalsIgnoreCase("Plain"))
-		slantVal = kMacFontRegular;
+Common::String MacFontManager::getNameFromSlant(int slantVal) {
 
-	return slantVal;
+	Common::StringArray tokens;
+	if (slantVal == kMacFontRegular)
+		return Common::String("plain");
+
+	if (slantVal & kMacFontBold)
+		tokens.push_back("bold");
+	if (slantVal & kMacFontItalic)
+		tokens.push_back("italic");
+	if (slantVal & kMacFontUnderline)
+		tokens.push_back("underline");
+	if (slantVal & kMacFontShadow)
+		tokens.push_back("shadow");
+	if (slantVal & kMacFontOutline)
+		tokens.push_back("outline");
+	if (slantVal & kMacFontCondense)
+		tokens.push_back("condense");
+	if (slantVal & kMacFontOutline)
+		tokens.push_back("extend");
+
+	if (tokens.begin() == tokens.end())
+		return *tokens.begin();
+
+	Common::String result = *tokens.begin();
+	for (auto it = tokens.begin() + 1; it != tokens.end(); it++) {
+		result += ",";
+		result += *it;
+	}
+
+	return result;
 }
 
 int MacFontManager::registerFontName(Common::String name, int preferredId) {
diff --git a/graphics/macgui/macfontmanager.h b/graphics/macgui/macfontmanager.h
index 2ee00ac1899..222d5a365e3 100644
--- a/graphics/macgui/macfontmanager.h
+++ b/graphics/macgui/macfontmanager.h
@@ -195,6 +195,7 @@ public:
 
 	void forceBuiltinFonts() { _builtInFonts = true; }
 	int parseSlantFromName(const Common::String &name);
+	Common::String getNameFromSlant(int slantVal);
 
 	const Common::Array<MacFontFamily *> &getFontFamilies() { return _fontFamilies; }
 
diff --git a/graphics/macgui/mactext.cpp b/graphics/macgui/mactext.cpp
index b47a7ef0ec0..ae453efa56d 100644
--- a/graphics/macgui/mactext.cpp
+++ b/graphics/macgui/mactext.cpp
@@ -496,11 +496,7 @@ void MacText::setTextSlant(int textSlant, int start, int end) {
 void MacText::enforceTextSlant(int textSlant) {
 	for (uint i = 0; i < _canvas._text.size(); i++) {
 		for (uint j = 0; j < _canvas._text[i].chunks.size(); j++) {
-			if (textSlant) {
-				_canvas._text[i].chunks[j].textSlant |= textSlant;
-			} else {
-				_canvas._text[i].chunks[j].textSlant = textSlant;
-			}
+			_canvas._text[i].chunks[j].textSlant = textSlant;
 		}
 	}
 
@@ -509,6 +505,12 @@ void MacText::enforceTextSlant(int textSlant) {
 	_contentIsDirty = true;
 }
 
+// Return the number of rows of text in the rendered output.
+// This means e.g. a line of text that wraps will count as 2 or more rows.
+int MacText::getRowCount() {
+	return (int)_canvas._text.size();
+}
+
 // this maybe need to amend
 // currently, we just return the text size of first character.
 int MacText::getTextSize(int start, int end) {
diff --git a/graphics/macgui/mactext.h b/graphics/macgui/mactext.h
index 552c2f3a6dd..c9bec5eb593 100644
--- a/graphics/macgui/mactext.h
+++ b/graphics/macgui/mactext.h
@@ -94,6 +94,8 @@ public:
 	int getTextFont() { return _defaultFormatting.fontId; }
 	void enforceTextFont(uint16 fontId);
 
+	int getRowCount();
+
 	// because currently, we are counting linespacing as font height
 	int getTextSize() { return _defaultFormatting.fontSize; }
 	void setTextSize(int textSize);
@@ -107,6 +109,7 @@ public:
 	int getTextFont(int start, int end);
 	void setTextFont(int fontId, int start, int end);
 
+	int getTextSlant() { return _defaultFormatting.textSlant; }
 	int getTextSlant(int start, int end);
 	void setTextSlant(int textSlant, int start, int end);
 	void enforceTextSlant(int textSlant);
diff --git a/graphics/macgui/mactextwindow.h b/graphics/macgui/mactextwindow.h
index 6c0607bc6ce..ba8df1ddc0f 100644
--- a/graphics/macgui/mactextwindow.h
+++ b/graphics/macgui/mactextwindow.h
@@ -64,7 +64,28 @@ public:
 	void clearSelection();
 	Common::U32String cutSelection();
 	const SelectedText *getSelectedText() { return &_selectedText; }
+	uint32 getTextColor() { return _mactext->getTextColor(); }
+	uint32 getTextColor(int start, int end) { return _mactext->getTextColor(start, end); }
+	void setTextColor(uint32 color, int start, int end) { return _mactext->setTextColor(color, start, end); }
+	int getTextFont() { return _mactext->getTextFont(); }
+	int getTextFont(int start, int end) { return _mactext->getTextFont(start, end); }
+	int getTextSlant() { return _mactext->getTextSlant(); }
+	int getTextSlant(int start, int end) { return _mactext->getTextSlant(start, end); }
 	int getTextHeight() { return _mactext->getTextHeight(); }
+	Common::U32String getTextChunk(int startRow, int startCol, int endRow, int endCol, bool formatted = false, bool newlines = true) { return _mactext->getTextChunk(startRow, startCol, endRow, endCol, formatted, newlines); }
+	Common::U32String getPlainText() { return _mactext->getPlainText(); }
+	Common::U32String getEditedString() { return _mactext->getEditedString(); };
+	void enforceTextFont(uint16 fontId) { return _mactext->enforceTextFont(fontId); }
+	void setTextFont(uint16 fontId, int start, int end) { return _mactext->setTextFont(fontId, start, end); }
+	void enforceTextSlant(int textSlant) { return _mactext->enforceTextSlant(textSlant); }
+	void setTextSlant(int textSlant, int start, int end) { return _mactext->setTextSlant(textSlant, start, end); }
+	int getRowCount() { return _mactext->getRowCount(); }
+	int getLineSpacing() { return _mactext->getLineSpacing(); }
+	int getTextSize() { return _mactext->getTextSize(); }
+	int getTextSize(int start, int end) { return _mactext->getTextSize(start, end); }
+	void setTextSize(int textSize) { return _mactext->setTextSize(textSize); }
+	void setTextSize(int textSize, int start, int end) { return _mactext->setTextSize(textSize, start, end); }
+
 	int getMouseLine(int x, int y);
 
 	/**


Commit: 7362ec3cb15b5cb199646b4c8526a6b82113dd22
    https://github.com/scummvm/scummvm/commit/7362ec3cb15b5cb199646b4c8526a6b82113dd22
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Fix libResourceID usage for multiple casts

Changed paths:
    engines/director/cast.cpp
    engines/director/fonts.cpp


diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index c4bd3cd7440..305d35fb952 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -640,8 +640,12 @@ void Cast::loadCast() {
 	if (!_loadedCast)
 		_loadedCast = new Common::HashMap<int, CastMember *>();
 
+	// External casts only have one library ID, so instead
+	// we use the movie's mapping.
+	uint16 libResourceId = _isExternal ? 1024 : _libResourceId;
+
 	if (cast.size() > 0) {
-		debugC(2, kDebugLoading, "****** Loading CASt resources for libId %d (%s), resourceId %d", _castLibID, _castName.c_str(), _libResourceId);
+		debugC(2, kDebugLoading, "****** Loading CASt resources for libId %d (%s), resourceId %d", _castLibID, _castName.c_str(), libResourceId);
 
 		int idx = 0;
 
@@ -650,7 +654,7 @@ void Cast::loadCast() {
 			// Only load cast members which belong to the requested library ID.
 			// External casts only have one library ID, so instead
 			// we use the movie's mapping.
-			if (res.libResourceId != _libResourceId && !_isExternal) {
+			if (res.libResourceId != libResourceId) {
 				debugC(5, kDebugLoading, "SKIPPED - CASt: resource %d, castId %d, libResourceId %d", iterator, res.castId, res.libResourceId);
 				continue;
 			}
@@ -728,7 +732,7 @@ void Cast::loadCast() {
 	if (_version >= kFileVer400 && !debugChannelSet(-1, kDebugNoBytecode)) {
 		// Try to load script context
 		// Even for multiple casts, ID is 1024
-		if ((r = _castArchive->getFirstResource(MKTAG('L', 'c', 't', 'x'), 1024)) != nullptr) {
+		if ((r = _castArchive->getFirstResource(MKTAG('L', 'c', 't', 'x'), libResourceId)) != nullptr) {
 			loadLingoContext(*r);
 			delete r;
 		}
@@ -1353,15 +1357,6 @@ void Cast::loadCastInfo(Common::SeekableReadStreamEndian &stream, uint16 id) {
 
 	InfoEntries castInfo = Movie::loadInfoEntries(stream, _version);
 
-	debugCN(4, kDebugLoading, "Cast::loadCastInfo(): castId: %s str(%d): '", numToCastNum(id), castInfo.strings.size());
-
-	for (uint i = 0; i < castInfo.strings.size(); i++) {
-		debugCN(4, kDebugLoading, "%s'", utf8ToPrintable(castInfo.strings[i].readString()).c_str());
-		if (i != castInfo.strings.size() - 1)
-			debugCN(4, kDebugLoading, ", '");
-	}
-	debugC(4, kDebugLoading, "'");
-
 	CastMemberInfo *ci = new CastMemberInfo();
 	Common::MemoryReadStreamEndian *entryStream;
 	CastMember *member = _loadedCast->getVal(id);
@@ -1415,6 +1410,8 @@ void Cast::loadCastInfo(Common::SeekableReadStreamEndian &stream, uint16 id) {
 	case 0:
 		break;
 	}
+	debugC(4, kDebugLoading, "Cast::loadCastInfo(): castId: %d, size: %d, script: %s, name: %s, directory: %s, fileName: %s, type: %s",
+			id, castInfo.strings.size(), ci->script.c_str(), ci->name.c_str(), ci->directory.c_str(), ci->fileName.c_str(), ci->type.c_str());
 
 	// For D4+ we may force Lingo scripts
 	if (_version < kFileVer400 || debugChannelSet(-1, kDebugNoBytecode)) {
@@ -1618,7 +1615,7 @@ void Cast::rebuildCastNameCache() {
 			if (!_castsNames.contains(cname) || (_castsNames.getVal(cname) > it._key)) {
 				_castsNames[cname] = it._key;
 			} else {
-				debugC(4, kDebugLoading, "Cast::rebuildCastNameCache(): duplicate cast name: %s for castIDs: %s %s", cname.c_str(), numToCastNum(it._key), numToCastNum(_castsNames[it._value->name]));
+				debugC(4, kDebugLoading, "Cast::rebuildCastNameCache(): duplicate cast name: %s for castIDs: %d %d ", cname.c_str(), it._key, _castsNames[it._value->name]);
 			}
 		}
 	}
diff --git a/engines/director/fonts.cpp b/engines/director/fonts.cpp
index 59a23c623f0..7a853d5a442 100644
--- a/engines/director/fonts.cpp
+++ b/engines/director/fonts.cpp
@@ -343,10 +343,10 @@ bool Cast::readFXmpLine(Common::SeekableReadStreamEndian &stream) {
 
 			if (fromPlatform == Common::kPlatformMacintosh) {
 				_macCharsToWin[fromChar] = toChar;
-				debugC(3, kDebugLoading, "Cast::readFXmpLine: Mapping Mac char %d to Win char %d", fromChar, toChar);
+				debugC(8, kDebugLoading, "Cast::readFXmpLine: Mapping Mac char %d to Win char %d", fromChar, toChar);
 			} else {
 				_winCharsToMac[fromChar] = toChar;
-				debugC(3, kDebugLoading, "Cast::readFXmpLine: Mapping Win char %d to Mac char %d", fromChar, toChar);
+				debugC(8, kDebugLoading, "Cast::readFXmpLine: Mapping Win char %d to Mac char %d", fromChar, toChar);
 			}
 
 			tok = readFXmpToken(stream);


Commit: 57f478fa0377ccb36e39d273cca8329f766fca1c
    https://github.com/scummvm/scummvm/commit/57f478fa0377ccb36e39d273cca8329f766fca1c
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Fix castLib object properties

Changed paths:
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.h


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index e6e410f3f7f..8f0f131cdd5 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1970,6 +1970,90 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 	member->setField(field, d);
 }
 
+Datum Lingo::getTheCastLib(Datum &id1, int field) {
+	Datum d;
+	if (id1.type != CASTLIBREF) {
+		warning("Lingo::getTheCastLib(): Expected CASTLIBREF, not %s", id1.type2str());
+		return d;
+	}
+
+	Movie *movie = _vm->getCurrentMovie();
+	if (!movie) {
+		warning("Lingo::getTheCast(): No movie loaded");
+		return d;
+	}
+	Cast *cast = movie->getCast(CastMemberID(0, id1.u.i));
+	if (!cast) {
+		g_lingo->lingoError("Lingo::getTheCastLib(): Cast lib %s not found", id1.asString().c_str());
+		return d;
+	}
+
+	switch (field) {
+	case kTheFileName:
+		d = cast->getArchive()->getPathName().toString(g_director->_dirSeparator);
+		break;
+	case kTheName:
+		d = cast->getCastName();
+		break;
+	case kTheNumber:
+		d = cast->_castLibID;
+		break;
+	case kThePreLoadMode:
+		warning("STUB: Lingo::getTheCastLib(): preLoadMode not implemented");
+		break;
+	case kTheSelectionField:
+		warning("STUB: Lingo::getTheCastLib(): selection not implemented");
+		d.type = ARRAY;
+		d.u.farr = new FArray();
+		d.u.farr->arr.push_back(1);
+		d.u.farr->arr.push_back(1);
+		break;
+	default:
+		break;
+	}
+
+	return d;
+}
+
+void Lingo::setTheCastLib(Datum &id1, int field, Datum &d) {
+	if (id1.type != CASTLIBREF) {
+		warning("Lingo::setTheCastLib(): Expected CASTLIBREF, not %s", id1.type2str());
+		return;
+	}
+	Movie *movie = _vm->getCurrentMovie();
+	if (!movie) {
+		warning("Lingo::setTheCastLib(): No movie loaded");
+		return;
+	}
+	Cast *cast = movie->getCast(CastMemberID(0, id1.u.i));
+	if (!cast) {
+		g_lingo->lingoError("Lingo::setTheCastLib(): Cast lib %s not found", id1.asString().c_str());
+		return;
+	}
+
+	switch (field) {
+	case kTheFileName:
+		warning("STUB: Lingo::setTheCastLib(): fileName not implemented");
+		break;
+	case kTheName:
+		warning("STUB: Lingo::setTheCastLib(): name not implemented");
+		break;
+	case kTheNumber:
+		warning("Lingo::setTheCastLib(): number is read-only");
+		break;
+	case kThePreLoadMode:
+		warning("STUB: Lingo::setTheCastLib(): preLoadMode not implemented");
+		break;
+	case kTheSelectionField:
+		warning("STUB: Lingo::setTheCastLib(): selection not implemented");
+		break;
+	default:
+		warning("STUB: Lingo::setTheCastLib(): unknown property %d", field);
+		break;
+	}
+}
+
+
 Datum Lingo::getTheField(Datum &id1, int field) {
 	Datum d;
 
@@ -2257,21 +2341,12 @@ void Lingo::getObjectProp(Datum &obj, Common::String &propName) {
 		g_lingo->push(d);
 		return;
 	} else if (obj.type == CASTLIBREF) {
-		Movie *movie = _vm->getCurrentMovie();
-		if (!movie) {
-			g_lingo->lingoError("Lingo::getObjectProp(): No movie loaded");
-			g_lingo->push(d);
-			return;
-		}
-		Cast *cast = movie->getCast(CastMemberID(0, obj.u.i));
-		if (!cast) {
-			g_lingo->lingoError("Lingo::getObjectProp(): CastLib %d not found", obj.u.i);
-			g_lingo->push(d);
-			return;
+		Common::String key = Common::String::format("%d%s", kTheCastLib, propName.c_str());
+		if (_theEntityFields.contains(key)) {
+			d = getTheCastLib(obj, _theEntityFields[key]->field);
 		}
-
-
-
+		g_lingo->push(d);
+		return;
 	}
 
 	if (_builtinFuncs.contains(propName) && _builtinFuncs[propName].nargs == 1) {
@@ -2344,17 +2419,10 @@ void Lingo::setObjectProp(Datum &obj, Common::String &propName, Datum &val) {
 			g_lingo->lingoError("Lingo::setObjectProp(): %s has no property '%s'", id.asString().c_str(), propName.c_str());
 		}
 	} else if (obj.type == CASTLIBREF) {
-		Movie *movie = _vm->getCurrentMovie();
-		if (!movie) {
-			g_lingo->lingoError("Lingo::setObjectProp(): No movie loaded");
-			return;
-		}
-		Cast *cast = movie->getCast(CastMemberID(0, obj.u.i));
-		if (!cast) {
-			g_lingo->lingoError("Lingo::setObjectProp(): CastLib %d not found", obj.u.i);
-			return;
+		Common::String key = Common::String::format("%d%s", kTheCastLib, propName.c_str());
+		if (_theEntityFields.contains(key)) {
+			setTheCastLib(obj, _theEntityFields[key]->field, val);
 		}
-
 	} else {
 		g_lingo->lingoError("Lingo::setObjectProp: Invalid object: %s", obj.asString(true).c_str());
 	}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 7118c611105..ffadce20d9b 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -484,6 +484,8 @@ public:
 	void setTheSprite(Datum &id, int field, Datum &d);
 	Datum getTheCast(Datum &id, int field);
 	void setTheCast(Datum &id, int field, Datum &d);
+	Datum getTheCastLib(Datum &id, int field);
+	void setTheCastLib(Datum &id, int field, Datum &d);
 	Datum getTheField(Datum &id1, int field);
 	void setTheField(Datum &id1, int field, Datum &d);
 	Datum getTheChunk(Datum &chunk, int field);


Commit: a26372cd2ef9bf5a4c17e111fa6e9cd64ed9b31b
    https://github.com/scummvm/scummvm/commit/a26372cd2ef9bf5a4c17e111fa6e9cd64ed9b31b
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Improve support for parsing multiplexed CastMemberIDs

Changed paths:
    engines/director/lingo/lingo.cpp
    engines/director/types.h


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 118e6affd59..f8205245593 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1923,7 +1923,7 @@ CastMemberID Lingo::resolveCastMember(const Datum &memberID, const Datum &castLi
 
 CastMemberID Lingo::toCastMemberID(const Datum &member, const Datum &castLib) {
 	// Used specifically for unpacking CastMemberIDs when provided by the bytecode
-	// as two Datums. This means no multiplex IDs.
+	// as two Datums. Multiplex IDs are supported, but auto-truncated.
 	Movie *movie = g_director->getCurrentMovie();
 	if (!movie) {
 		warning("Lingo::toCastMemberID: No movie set");
@@ -1950,13 +1950,9 @@ CastMemberID Lingo::toCastMemberID(const Datum &member, const Datum &castLib) {
 		if (member.isCastRef()) {
 			res = member.asMemberID();
 		} else if (member.isNumeric()) {
-			if (libId == 0) {
-				// When specifying 0 as the castlib, D5 will assume this
-				// means the default (i.e. first) cast library. It will not
-				// try other libraries for matches if the member is a number.
-				libId = DEFAULT_CAST_LIB;
-			}
-			res = CastMemberID(member.asInt(), libId);
+			res = CastMemberID().fromMultiplex(member.asInt());
+			if (libId != 0)
+				res.castLib = libId;
 		} else {
 			res = movie->getCastMemberIDByNameAndType(member.asString(), libId, kCastTypeAny);
 		}
diff --git a/engines/director/types.h b/engines/director/types.h
index c9573260188..72fd4772e20 100644
--- a/engines/director/types.h
+++ b/engines/director/types.h
@@ -428,13 +428,13 @@ struct CastMemberID {
 	CastMemberID fromMultiplex(int multiplexID) {
 		if (multiplexID < 0)
 			return CastMemberID(multiplexID, -1);
-		return CastMemberID(multiplexID % 0x20000, 1 + (multiplexID / 0x20000));
+		return CastMemberID(multiplexID % 0x20000, 1 + (multiplexID >> 17));
 	}
 
 	int toMultiplex() {
 		if (castLib < 0)
 			return member;
-		return member + 0x20000 * (castLib - 1);
+		return (member % 0x20000) + ((castLib - 1) << 17);
 	}
 };
 


Commit: c967f946a75164f4f6213764c17bee39e2909273
    https://github.com/scummvm/scummvm/commit/c967f946a75164f4f6213764c17bee39e2909273
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add new properties for SoundCastMember

Changed paths:
    engines/director/castmember/sound.cpp
    engines/director/castmember/sound.h
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h
    engines/director/sound.cpp
    engines/director/sound.h


diff --git a/engines/director/castmember/sound.cpp b/engines/director/castmember/sound.cpp
index c87769f83f7..ddd05a552b4 100644
--- a/engines/director/castmember/sound.cpp
+++ b/engines/director/castmember/sound.cpp
@@ -23,6 +23,7 @@
 #include "director/cast.h"
 #include "director/sound.h"
 #include "director/castmember/sound.h"
+#include "director/lingo/lingo-the.h"
 
 namespace Director {
 
@@ -145,4 +146,57 @@ void SoundCastMember::unload() {
 	_loaded = false;
 }
 
+bool SoundCastMember::hasField(int field) {
+	switch (field) {
+	case kTheChannelCount:
+	case kTheSampleRate:
+	case kTheSampleSize:
+		return true;
+	default:
+		break;
+	}
+	return CastMember::hasField(field);
+}
+
+Datum SoundCastMember::getField(int field) {
+	Datum d;
+	load();
+	if (!_audio) {
+		warning("SoundCastMember::getField(): Audio not found");
+		return d;
+	}
+
+	switch (field) {
+	case kTheChannelCount:
+		d = _audio->getChannelCount();
+		break;
+	case kTheSampleRate:
+		d = _audio->getSampleRate();
+		break;
+	case kTheSampleSize:
+		d = _audio->getSampleSize();
+		break;
+	default:
+		d = CastMember::getField(field);
+	}
+
+	return d;
+}
+
+bool SoundCastMember::setField(int field, const Datum &d) {
+	switch (field) {
+	case kTheChannelCount:
+	case kTheSampleRate:
+	case kTheSampleSize:
+		warning("SoundCastMember::setField(): Attempt to set read-only field %s of cast %d", g_lingo->field2str(field), _castId);
+		return false;
+	default:
+		break;
+	}
+
+	return CastMember::setField(field, d);
+}
+
+
+
 } // End of namespace Director
diff --git a/engines/director/castmember/sound.h b/engines/director/castmember/sound.h
index afb1fcad63e..9c2b85c198f 100644
--- a/engines/director/castmember/sound.h
+++ b/engines/director/castmember/sound.h
@@ -38,6 +38,10 @@ public:
 	void unload() override;
 	Common::String formatInfo() override;
 
+	bool hasField(int field) override;
+	Datum getField(int field) override;
+	bool setField(int field, const Datum &value) override;
+
 	bool _looping;
 	AudioDecoder *_audio;
 };
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8f0f131cdd5..5b99f6077e2 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -314,6 +314,11 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"filled",		kTheFilled,		500 },//						D5 p
 	{ kTheCast,		"lineSize",		kTheLineSize,	500 },//						D5 p
 
+	// SoundCastMember fields
+	{ kTheCast,		"channelCount",	kTheChannelCount,500 },//						D5 p
+	{ kTheCast,		"sampleRate",	kTheSampleRate,	500 },//						D5 p
+	{ kTheCast,		"sampleSize",	kTheSampleSize,	500 },//						D5 p
+
 	// TransitionCastMember fields
 	{ kTheCast,		"changeArea",	kTheChangeArea,	500 },//						D5 p
 	{ kTheCast,		"chunkSize",	kTheChunkSize,	500 },//						D5 p
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index 30e0287fc25..a580e125580 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -184,6 +184,7 @@ enum TheFieldType {
 	kTheCastType,
 	kTheCenter,
 	kTheChangeArea,
+	kTheChannelCount,
 	kTheCheckMark,
 	kTheChunkSize,
 	kTheConstraint,
@@ -241,6 +242,8 @@ enum TheFieldType {
 	kTheRect,
 	kTheRegPoint,
 	kTheRight,
+	kTheSampleRate,
+	kTheSampleSize,
 	kTheScoreColor,
 	kTheScript,
 	kTheScriptNum,
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index a3f462cca97..89a44a1da23 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -673,6 +673,7 @@ SNDDecoder::SNDDecoder()
 	_channels = 0;
 	_size = 0;
 	_rate = 0;
+	_bits = 0;
 	_flags = 0;
 	_loopStart = _loopEnd = 0;
 }
@@ -764,7 +765,7 @@ bool SNDDecoder::processBufferCommand(Common::SeekableReadStreamEndian &stream)
 		return false;
 	}
 	uint32 frameCount = 0;
-	uint16 bits = 8;
+	_bits = 8;
 	if (encoding == 0x00) {
 		// Standard sound header
 		frameCount = param / _channels;
@@ -779,7 +780,7 @@ bool SNDDecoder::processBufferCommand(Common::SeekableReadStreamEndian &stream)
 		/*uint32 markerChunk =*/stream.readUint32();
 		/*uint32 instrumentsChunk =*/stream.readUint32();
 		/*uint32 aesRecording =*/stream.readUint32();
-		bits = stream.readUint16();
+		_bits = stream.readUint16();
 
 		// future use
 		stream.readUint16();
@@ -797,9 +798,9 @@ bool SNDDecoder::processBufferCommand(Common::SeekableReadStreamEndian &stream)
 
 	_flags = 0;
 	_flags |= (_channels == 2) ? Audio::FLAG_STEREO : 0;
-	_flags |= (bits == 16) ? Audio::FLAG_16BITS : 0;
-	_flags |= (bits == 8) ? Audio::FLAG_UNSIGNED : 0;
-	_size = frameCount * _channels * (bits == 16 ? 2 : 1);
+	_flags |= (_bits == 16) ? Audio::FLAG_16BITS : 0;
+	_flags |= (_bits == 8) ? Audio::FLAG_UNSIGNED : 0;
+	_size = frameCount * _channels * (_bits == 16 ? 2 : 1);
 
 	_data = (byte *)malloc(_size);
 	assert(_data);
diff --git a/engines/director/sound.h b/engines/director/sound.h
index dc132273ad6..b1d4aae19cd 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -226,6 +226,9 @@ public:
 	virtual ~AudioDecoder() {};
 public:
 	virtual Audio::AudioStream *getAudioStream(bool looping = false, bool forPuppet = false, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES) { return nullptr; }
+	virtual int getChannelCount() { return 0; }
+	virtual int getSampleRate() { return 0; }
+	virtual int getSampleSize() { return 0; }
 };
 
 class SNDDecoder : public AudioDecoder {
@@ -241,12 +244,16 @@ public:
 	bool hasLoopBounds();
 	void resetLoopBounds();
 	bool hasValidLoopBounds();
+	int getChannelCount() override { return _channels; }
+	int getSampleRate() override { return _rate; }
+	int getSampleSize() override { return _bits; }
 
 private:
 	byte *_data;
 	uint16 _channels;
 	uint32 _size;
 	uint16 _rate;
+	uint16 _bits;
 	byte _flags;
 	uint32 _loopStart;
 	uint32 _loopEnd;


Commit: 04d5c36679afd3f3b251d2bd872f8998072cc21c
    https://github.com/scummvm/scummvm/commit/04d5c36679afd3f3b251d2bd872f8998072cc21c
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add new properties for ShapeCastMember

Changed paths:
    engines/director/castmember/shape.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/castmember/shape.cpp b/engines/director/castmember/shape.cpp
index 4fcaf65a30f..7841bb0426b 100644
--- a/engines/director/castmember/shape.cpp
+++ b/engines/director/castmember/shape.cpp
@@ -112,6 +112,8 @@ bool ShapeCastMember::hasField(int field) {
 	switch (field) {
 	case kTheFilled:
 	case kTheLineSize:
+	case kThePattern:
+	case kTheShapeType:
 		return true;
 	default:
 		break;
@@ -129,6 +131,31 @@ Datum ShapeCastMember::getField(int field) {
 	case kTheLineSize:
 		d = Datum(_lineThickness);
 		break;
+	case kThePattern:
+		d = Datum(_pattern);
+		break;
+	case kTheShapeType:
+		switch (_shapeType) {
+		case kShapeRectangle:
+			d = Datum("rect");
+			d.type = SYMBOL;
+			break;
+		case kShapeRoundRect:
+			d = Datum("roundRect");
+			d.type = SYMBOL;
+			break;
+		case kShapeOval:
+			d = Datum("oval");
+			d.type = SYMBOL;
+			break;
+		case kShapeLine:
+			d = Datum("line");
+			d.type = SYMBOL;
+			break;
+		default:
+			break;
+		}
+		break;
 	default:
 		d = CastMember::getField(field);
 		break;
@@ -145,6 +172,24 @@ bool ShapeCastMember::setField(int field, const Datum &d) {
 	case kTheLineSize:
 		_lineThickness = d.asInt();
 		return true;
+	case kThePattern:
+		_pattern = d.asInt();
+		return true;
+	case kTheShapeType:
+		if (d.type == SYMBOL) {
+			Common::String name = *d.u.s;
+			if (name.equalsIgnoreCase("rect")) {
+				_shapeType = kShapeRectangle;
+			} else if (name.equalsIgnoreCase("roundRect")) {
+				_shapeType = kShapeRoundRect;
+			} else if (name.equalsIgnoreCase("oval")) {
+				_shapeType = kShapeOval;
+			} else if (name.equalsIgnoreCase("line")) {
+				_shapeType = kShapeLine;
+			}
+			return true;
+		}
+		break;
 	default:
 		break;
 	}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 5b99f6077e2..33e70cc31da 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -313,6 +313,8 @@ const TheEntityField fields[] = {
 	// ShapeCastMember fields
 	{ kTheCast,		"filled",		kTheFilled,		500 },//						D5 p
 	{ kTheCast,		"lineSize",		kTheLineSize,	500 },//						D5 p
+	{ kTheCast,		"pattern",		kThePattern,	500 },//						D5 p
+	{ kTheCast,		"shapeType",	kTheShapeType,	500 },//						D5 p
 
 	// SoundCastMember fields
 	{ kTheCast,		"channelCount",	kTheChannelCount,500 },//						D5 p
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index a580e125580..a876273db68 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -250,6 +250,7 @@ enum TheFieldType {
 	kTheScriptText,
 	kTheScriptsEnabled,
 	kTheSelectionField,
+	kTheShapeType,
 	kTheShort,
 	kTheSize,
 	kTheSound,


Commit: f40f9fdadae48f425d9c6aad16c53e8af27c1297
    https://github.com/scummvm/scummvm/commit/f40f9fdadae48f425d9c6aad16c53e8af27c1297
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add the castLibNum sprite property

Changed paths:
    engines/director/lingo/lingo-the.cpp


diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 33e70cc31da..9cbd7143ad5 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -187,6 +187,7 @@ const TheEntityField fields[] = {
 	{ kTheSprite,	"blend",		kTheBlend,		400 },//				D4 p
 	{ kTheSprite,	"bottom",		kTheBottom,		200 },// D2 p
 	{ kTheSprite,	"castNum",		kTheCastNum,	200 },// D2 p
+	{ kTheSprite,	"castLibNum",	kTheCastLibNum,	500 },//					D5 p
 	{ kTheSprite,	"constraint",	kTheConstraint, 200 },// D2 p
 	{ kTheSprite,	"cursor",		kTheCursor,		200 },// D2 p
 	{ kTheSprite,	"editableText", kTheEditableText,400 },//				D4 p
@@ -1484,12 +1485,12 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
 			d = sprite->_castId.member;
 		}
 		break;
-	case kTheMemberNum:
-		d = sprite->_castId.member;
-		break;
 	case kTheCastLibNum:
 		d = sprite->_castId.castLib;
 		break;
+	case kTheMemberNum:
+		d = sprite->_castId.member;
+		break;
 	case kTheConstraint:
 		d = (int)channel->_constraint;
 		break;
@@ -1670,14 +1671,15 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 		}
 		break;
 	case kTheCastNum:
+	case kTheCastLibNum:
 	case kTheMemberNum:
 		{
 			CastMemberID castId = d.asMemberID();
-			if (g_director->getVersion() < 500 || field == kTheMemberNum) {
+			if (field == kTheMemberNum) {
 				// Setting the cast ID as a number will preserve whatever is in castLib
-				if (d.isNumeric() && (sprite->_castId.castLib != 0)) {
-					castId = CastMemberID(d.asInt(), sprite->_castId.castLib);
-				}
+				castId = CastMemberID(d.asInt(), sprite->_castId.castLib);
+			} else if (field == kTheCastLibNum) {
+				castId = CastMemberID(sprite->_castId.member, d.asInt());
 			}
 			CastMember *castMember = movie->getCastMember(castId);
 


Commit: 28a17b245f02231818779f8a845c3aa67a5831cd
    https://github.com/scummvm/scummvm/commit/28a17b245f02231818779f8a845c3aa67a5831cd
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add new properties for MovieCastMember

Changed paths:
    engines/director/castmember/movie.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/castmember/movie.cpp b/engines/director/castmember/movie.cpp
index bb94fc2c910..2d4ad24d79e 100644
--- a/engines/director/castmember/movie.cpp
+++ b/engines/director/castmember/movie.cpp
@@ -66,9 +66,13 @@ MovieCastMember::MovieCastMember(Cast *cast, uint16 castId, MovieCastMember &sou
 
 bool MovieCastMember::hasField(int field) {
 	switch (field) {
-	case kTheSound:
 	case kTheCenter:
+	case kTheIdleHandlerPeriod:
+	case kThePaletteMapping:
+	case kTheScoreSelection:
 	case kTheScriptsEnabled:
+	case kTheSound:
+	case kTheUpdateLock:
 		return true;
 	default:
 		break;
@@ -80,15 +84,27 @@ Datum MovieCastMember::getField(int field) {
 	Datum d;
 
 	switch (field) {
-	case kTheSound:
-		d = Datum(_enableSound);
-		break;
 	case kTheCenter:
 		d = Datum((int)_center);
 		break;
+	case kTheIdleHandlerPeriod:
+		warning("STUB: MovieCastMember::getField(): idleHandlerPeriod not implemented");
+		break;
+	case kThePaletteMapping:
+		warning("STUB: MovieCastMember::getField(): paletteMapping not implemented");
+		break;
+	case kTheScoreSelection:
+		warning("STUB: MovieCastMember::getField(): scoreSelection not implemented");
+		break;
 	case kTheScriptsEnabled:
 		d = Datum(_enableScripts);
 		break;
+	case kTheSound:
+		d = Datum(_enableSound);
+		break;
+	case kTheUpdateLock:
+		warning("STUB: MovieCastMember::getField(): updateLock not implemented");
+		break;
 	default:
 		d = CastMember::getField(field);
 		break;
@@ -99,15 +115,27 @@ Datum MovieCastMember::getField(int field) {
 
 bool MovieCastMember::setField(int field, const Datum &d) {
 	switch (field) {
-	case kTheSound:
-		_enableSound = (bool)d.asInt();
-		return true;
 	case kTheCenter:
 		_center = (bool)d.asInt();
 		return true;
+	case kTheIdleHandlerPeriod:
+		warning("STUB: MovieCastMember::setField(): idleHandlerPeriod not implemented");
+		return false;
+	case kThePaletteMapping:
+		warning("STUB: MovieCastMember::setField(): paletteMapping not implemented");
+		return false;
+	case kTheScoreSelection:
+		warning("STUB: MovieCastMember::setField(): scoreSelection not implemented");
+		return false;
 	case kTheScriptsEnabled:
 		_enableScripts = (bool)d.asInt();
 		return true;
+	case kTheSound:
+		_enableSound = (bool)d.asInt();
+		return true;
+	case kTheUpdateLock:
+		warning("STUB: MovieCastMember::setField(): updateLock not implemented");
+		return false;
 	default:
 		break;
 	}
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 9cbd7143ad5..42317796087 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -260,22 +260,25 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"sound",		kTheSound,		300 },//		D3.1 p // 0-1 off-on
 	{ kTheSprite,	"startTime",	kTheStartTime,	300 },//		D3.1 p
 	{ kTheSprite,	"stopTime",		kTheStopTime,	300 },//		D3.1 p
-	{ kTheSprite,	"trackCount",	kTheTrackCount, 500 },//					D5 p
-	{ kTheSprite,	"trackEnabled",	kTheTrackEnabled, 500 },//					D5 p
-	{ kTheSprite,	"trackNextKeyTime",	kTheTrackNextKeyTime, 500 },//					D5 p
-	{ kTheSprite,	"trackNextSampleTime",	kTheTrackNextSampleTime, 500 },//					D5 p
-	{ kTheSprite,	"trackPreviousKeyTime",	kTheTrackPreviousKeyTime, 500 },//					D5 p
-	{ kTheSprite,	"trackPreviousSampleTime",	kTheTrackPreviousKeyTime, 500 },//					D5 p
-	{ kTheSprite,	"trackStartTime",	kTheTrackStartTime, 500 },//					D5 p
+	{ kTheSprite,	"trackCount",	kTheTrackCount, 500 },//						D5 p
+	{ kTheSprite,	"trackEnabled",	kTheTrackEnabled, 500 },//						D5 p
+	{ kTheSprite,	"trackNextKeyTime",	kTheTrackNextKeyTime, 500 },//				D5 p
+	{ kTheSprite,	"trackNextSampleTime",	kTheTrackNextSampleTime, 500 },//		D5 p
+	{ kTheSprite,	"trackPreviousKeyTime",	kTheTrackPreviousKeyTime, 500 },//		D5 p
+	{ kTheSprite,	"trackPreviousSampleTime",	kTheTrackPreviousKeyTime, 500 },//	D5 p
+	{ kTheSprite,	"trackStartTime",	kTheTrackStartTime, 500 },//				D5 p
 	{ kTheSprite,	"trackStopTime",	kTheTrackStopTime, 500 },//					D5 p
-	{ kTheSprite,	"trackText",	kTheTrackText, 500 },//					D5 p
-	{ kTheSprite,	"trackType",	kTheTrackType, 500 },//					D5 p
+	{ kTheSprite,	"trackText",	kTheTrackText, 500 },//							D5 p
+	{ kTheSprite,	"trackType",	kTheTrackType, 500 },//							D5 p
 	{ kTheCast,		"video",		kTheVideo,		400 },//				D4 p
 	{ kTheSprite,	"volume",		kTheVolume,		300 },//		D3.1 p
 
 	// Movie fields
-	{ kTheCast,		"scriptsEnabled",	kTheScriptsEnabled,	500 },//			D5 p
-
+	{ kTheCast,		"idleHandlerPeriod",kTheIdleHandlerPeriod, 500 },//				D5 p
+	{ kTheCast,		"paletteMapping",	kThePaletteMapping,	500 },//				D5 p
+	{ kTheCast,		"scriptsEnabled",	kTheScriptsEnabled,	500 },//				D5 p
+	{ kTheCast,		"scoreSelection",	kTheScoreSelection,	500 },//				D5 p
+	{ kTheCast,		"updateLock",		kTheUpdateLock,		500 },//				D5 p
 
 	// Bitmap fields
 	{ kTheCast,		"depth",		kTheDepth,		400 },//				D4 p
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index a876273db68..df52e69017a 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -207,6 +207,7 @@ enum TheFieldType {
 	kTheHeight,
 	kTheHilite,
 	kTheImmediate,
+	kTheIdleHandlerPeriod,
 	kTheIdleReadChunkSize,
 	kTheInk,
 	kTheLast,
@@ -232,6 +233,7 @@ enum TheFieldType {
 	kTheNumber,
 	kThePageHeight,
 	kThePalette,
+	kThePaletteMapping,
 	kThePattern,
 	kThePausedAtStart,
 	kThePicture,
@@ -245,6 +247,7 @@ enum TheFieldType {
 	kTheSampleRate,
 	kTheSampleSize,
 	kTheScoreColor,
+	kTheScoreSelection,
 	kTheScript,
 	kTheScriptNum,
 	kTheScriptText,
@@ -281,6 +284,7 @@ enum TheFieldType {
 	kTheTrails,
 	kTheTransitionType,
 	kTheType,
+	kTheUpdateLock,
 	kTheVideo,
 	kTheVisibility,
 	kTheVisible,


Commit: 195ecca49159910159ad75c27db975f25244ee4a
    https://github.com/scummvm/scummvm/commit/195ecca49159910159ad75c27db975f25244ee4a
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add the paletteRef BitmapCastMember property

Changed paths:
    engines/director/castmember/bitmap.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 7561f75f28f..2e0092d3de2 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -755,6 +755,7 @@ bool BitmapCastMember::hasField(int field) {
 	case kTheDepth:
 	case kTheRegPoint:
 	case kThePalette:
+	case kThePaletteRef:
 	case kThePicture:
 		return true;
 	default:
@@ -784,6 +785,52 @@ Datum BitmapCastMember::getField(int field) {
 			d = Datum(_clut.member);
 		}
 		break;
+	case kThePaletteRef:
+		if (_clut.castLib > 0) {
+			d = _clut;
+		} else if (_clut.castLib == -1) {
+			switch (_clut.member) {
+			case kClutSystemMac:
+				d = Datum("systemMac");
+				d.type = SYMBOL;
+				break;
+			case kClutSystemWin:
+				d = Datum("systemWinDir4");
+				d.type = SYMBOL;
+				break;
+			case kClutSystemWinD5:
+				d = Datum("systemWin");
+				d.type = SYMBOL;
+				break;
+			case kClutGrayscale:
+				d = Datum("grayscale");
+				d.type = SYMBOL;
+				break;
+			case kClutMetallic:
+				d = Datum("metallic");
+				d.type = SYMBOL;
+				break;
+			case kClutNTSC:
+				d = Datum("NTSC");
+				d.type = SYMBOL;
+				break;
+			case kClutPastels:
+				d = Datum("pastels");
+				d.type = SYMBOL;
+				break;
+			case kClutRainbow:
+				d = Datum("rainbow");
+				d.type = SYMBOL;
+				break;
+			case kClutVivid:
+				d = Datum("vivid");
+				d.type = SYMBOL;
+				break;
+			default:
+				break;
+			}
+		}
+		break;
 	case kThePicture:
 		d.type = PICTUREREF;
 		d.u.picture = getPicture();
@@ -837,6 +884,39 @@ bool BitmapCastMember::setField(int field, const Datum &d) {
 			}
 			return true;
 		}
+	case kThePaletteRef:
+		{
+			CastMemberID newClut = _clut;
+			if (d.isCastRef()) {
+				newClut = *d.u.cast;
+			} else if (d.type == SYMBOL) {
+				Common::String name = *d.u.s;
+				if (name.equalsIgnoreCase("systemMac")) {
+					newClut = CastMemberID(kClutSystemMac, -1);
+				} else if (name.equalsIgnoreCase("systemWinDir4")) {
+					newClut = CastMemberID(kClutSystemWin, -1);
+				} else if (name.equalsIgnoreCase("systemWin")) {
+					newClut = CastMemberID(kClutSystemWinD5, -1);
+				} else if (name.equalsIgnoreCase("grayscale")) {
+					newClut = CastMemberID(kClutGrayscale, -1);
+				} else if (name.equalsIgnoreCase("metallic")) {
+					newClut = CastMemberID(kClutMetallic, -1);
+				} else if (name.equalsIgnoreCase("NTSC")) {
+					newClut = CastMemberID(kClutNTSC, -1);
+				} else if (name.equalsIgnoreCase("pastels")) {
+					newClut = CastMemberID(kClutPastels, -1);
+				} else if (name.equalsIgnoreCase("rainbow")) {
+					newClut = CastMemberID(kClutRainbow, -1);
+				} else if (name.equalsIgnoreCase("vivid")) {
+					newClut = CastMemberID(kClutVivid, -1);
+				}
+			}
+			if (newClut != _clut) {
+				_clut = newClut;
+				_modified = true;
+			}
+		}
+		return true;
 	case kThePicture:
 		if (d.type == PICTUREREF && d.u.picture != nullptr) {
 			setPicture(*d.u.picture);
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index ecd78db8555..2cbdf26050f 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -2640,7 +2640,7 @@ static const struct PaletteNames {
 	{ "Metallic", kClutMetallic },
 	//{ "Web 216", },
 	//{ "VGA", },
-	//{ "System - Win", },
+	{ "System - Win", kClutSystemWinD5 },
 	{ "SYSTEM - WIN (DIR 4)", kClutSystemWin },
 
 	// Japanese palette names.
@@ -2651,7 +2651,7 @@ static const struct PaletteNames {
 	{ "\x83p\x83>X\x83""e\x83\x8B", kClutPastels },						// パステル
 	{ "\x83r\x83>r\x83""b\x83h", kClutVivid },							// ビビッド
 	{ "\x83\x81\x83^\x83\x8A\x83""b\x83N", kClutMetallic },				// メタリック
-	// { "\x83V\x83X\x83""e\x83\x80 - Win", },							// システム - Win
+	{ "\x83V\x83X\x83""e\x83\x80 - Win", kClutSystemWinD5 },							// システム - Win
 	{ "\x83V\x83X\x83""e\x83\x80 - Win (Dir 4)", kClutSystemWin },		// システム - Win (Dir 4)
 };
 
@@ -2677,9 +2677,14 @@ void LB::b_puppetPalette(int nargs) {
 			Common::String palStr = d.asString();
 
 			for (int i = 0; i < ARRAYSIZE(paletteNames); i++) {
-				if (palStr.equalsIgnoreCase(paletteNames[i].name))
+				if (palStr.equalsIgnoreCase(paletteNames[i].name)) {
 					palette = CastMemberID(paletteNames[i].type, -1);
+					if (g_director->getVersion() < 500 && paletteNames[i].type == kClutSystemWinD5)
+						palette.member = kClutSystemWin;
+					break;
+				}
 			}
+
 		}
 		if (palette.isNull()) {
 			CastMember *member = movie->getCastMember(d.asMemberID());
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 42317796087..a2a52bf90b3 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -284,6 +284,7 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"depth",		kTheDepth,		400 },//				D4 p
 	{ kTheCast,		"regPoint",		kTheRegPoint,	400 },//				D4 p
 	{ kTheCast,		"palette",		kThePalette,	400 },//				D4 p
+	{ kTheCast,		"paletteRef",	kThePaletteRef,	500 },//				D4 p
 	{ kTheCast,		"picture",		kThePicture,	300 },//		D3 p
 
 	// TextCastMember fields
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index df52e69017a..f9f46d83fde 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -234,6 +234,7 @@ enum TheFieldType {
 	kThePageHeight,
 	kThePalette,
 	kThePaletteMapping,
+	kThePaletteRef,
 	kThePattern,
 	kThePausedAtStart,
 	kThePicture,


Commit: 098aef847f66d09806521f3249f4d19a92938a7d
    https://github.com/scummvm/scummvm/commit/098aef847f66d09806521f3249f4d19a92938a7d
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add new properties for DigitalVideoCastMember

Changed paths:
    engines/director/castmember/digitalvideo.cpp
    engines/director/lingo/lingo-builtins.cpp
    engines/director/lingo/lingo-builtins.h
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index 55b72fca55f..6e688038f9c 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -431,13 +431,11 @@ bool DigitalVideoCastMember::hasField(int field) {
 	case kTheDuration:
 	case kTheFrameRate:
 	case kTheLoop:
-	case kTheMovieRate:
-	case kTheMovieTime:
 	case kThePausedAtStart:
 	case kThePreLoad:
 	case kTheSound:
+	case kTheTimeScale:
 	case kTheVideo:
-	case kTheVolume:
 		return true;
 	default:
 		break;
@@ -490,6 +488,10 @@ Datum DigitalVideoCastMember::getField(int field) {
 	case kTheSound:
 		d = _enableSound;
 		break;
+	case kTheTimeScale:
+		warning("STUB: DigitalVideoCastMember::getField(): timeScale not implemented");
+		d = Datum(600); // quicktime default
+		break;
 	case kTheVideo:
 		d = _enableVideo;
 		break;
@@ -539,6 +541,9 @@ bool DigitalVideoCastMember::setField(int field, const Datum &d) {
 	case kTheSound:
 		_enableSound = (bool)d.asInt();
 		return true;
+	case kTheTimeScale:
+		warning("DigitalVideoCastMember::setField(): Attempt to set read-only field %s of cast %d", g_lingo->entity2str(field), _castId);
+		return false;
 	case kTheVideo:
 		_enableVideo = (bool)d.asInt();
 		return true;
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 2cbdf26050f..d09244c8dd4 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -249,6 +249,11 @@ static const BuiltinProto builtins[] = {
 	{ "numberOfItems",	LB::b_numberofitems,1, 1, 300, FBLTIN },	//			D3 f
 	{ "numberOfLines",	LB::b_numberoflines,1, 1, 300, FBLTIN },	//			D3 f
 	{ "numberOfWords",	LB::b_numberofwords,1, 1, 300, FBLTIN },	//			D3 f
+	// Digital video operations
+	{ "trackCount",		LB::b_trackCount,	1, 1, 500, FBLTIN },	//				D5 f
+	{ "trackStartTime",	LB::b_trackStartTime,1, 1, 500, FBLTIN },	//				D5 f
+	{ "trackStopTime",	LB::b_trackStopTime,1, 1, 500, FBLTIN },	//				D5 f
+	{ "trackType",		LB::b_trackType,	1, 1, 500, FBLTIN },	//				D5 f
 
 	// ScummVM Asserts: Used for testing ScummVM's Lingo implementation
 	{ "scummvmAssert",	LB::b_scummvmassert,1, 2, 200, HBLTIN },
@@ -3616,6 +3621,32 @@ void LB::b_numberofwords(int nargs) {
 	g_lingo->push(chunkRef.u.cref->startChunk);
 }
 
+void LB::b_trackCount(int nargs) {
+	g_lingo->printSTUBWithArglist("b_trackCount", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(1);
+}
+
+void LB::b_trackStartTime(int nargs) {
+	g_lingo->printSTUBWithArglist("b_trackStartTime", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(0);
+}
+
+void LB::b_trackStopTime(int nargs) {
+	g_lingo->printSTUBWithArglist("b_trackStopTime", nargs);
+	g_lingo->dropStack(nargs);
+	g_lingo->push(0);
+}
+
+void LB::b_trackType(int nargs) {
+	g_lingo->printSTUBWithArglist("b_trackType", nargs);
+	g_lingo->dropStack(nargs);
+	Datum result("video");
+	result.type = SYMBOL;
+	g_lingo->push(result);
+}
+
 void LB::b_scummvmassert(int nargs) {
 	Datum line = g_lingo->pop();
 	Datum d = g_lingo->pop();
diff --git a/engines/director/lingo/lingo-builtins.h b/engines/director/lingo/lingo-builtins.h
index a00b522757f..5da53477bbe 100644
--- a/engines/director/lingo/lingo-builtins.h
+++ b/engines/director/lingo/lingo-builtins.h
@@ -216,6 +216,11 @@ void b_numberofitems(int nargs);
 void b_numberoflines(int nargs);
 void b_numberofwords(int nargs);
 
+void b_trackCount(int nargs);
+void b_trackStartTime(int nargs);
+void b_trackStopTime(int nargs);
+void b_trackType(int nargs);
+
 void b_scummvmassert(int nargs);
 void b_scummvmassertequal(int nargs);
 void b_scummvmNoFatalError(int nargs);
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index a2a52bf90b3..935e2de6714 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -260,16 +260,13 @@ const TheEntityField fields[] = {
 	{ kTheCast,		"sound",		kTheSound,		300 },//		D3.1 p // 0-1 off-on
 	{ kTheSprite,	"startTime",	kTheStartTime,	300 },//		D3.1 p
 	{ kTheSprite,	"stopTime",		kTheStopTime,	300 },//		D3.1 p
-	{ kTheSprite,	"trackCount",	kTheTrackCount, 500 },//						D5 p
+	{ kTheCast,		"timeScale",	kTheTimeScale,	500 },//						D5 p
 	{ kTheSprite,	"trackEnabled",	kTheTrackEnabled, 500 },//						D5 p
 	{ kTheSprite,	"trackNextKeyTime",	kTheTrackNextKeyTime, 500 },//				D5 p
 	{ kTheSprite,	"trackNextSampleTime",	kTheTrackNextSampleTime, 500 },//		D5 p
 	{ kTheSprite,	"trackPreviousKeyTime",	kTheTrackPreviousKeyTime, 500 },//		D5 p
 	{ kTheSprite,	"trackPreviousSampleTime",	kTheTrackPreviousKeyTime, 500 },//	D5 p
-	{ kTheSprite,	"trackStartTime",	kTheTrackStartTime, 500 },//				D5 p
-	{ kTheSprite,	"trackStopTime",	kTheTrackStopTime, 500 },//					D5 p
 	{ kTheSprite,	"trackText",	kTheTrackText, 500 },//							D5 p
-	{ kTheSprite,	"trackType",	kTheTrackType, 500 },//							D5 p
 	{ kTheCast,		"video",		kTheVideo,		400 },//				D4 p
 	{ kTheSprite,	"volume",		kTheVolume,		300 },//		D3.1 p
 
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index f9f46d83fde..bb0605ae185 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -269,19 +269,16 @@ enum TheFieldType {
 	kTheTextHeight,
 	kTheTextSize,
 	kTheTextStyle,
+	kTheTimeScale,
 	kTheTitle,
 	kTheTitleVisible,
 	kTheTop,
-	kTheTrackCount,
 	kTheTrackEnabled,
 	kTheTrackNextKeyTime,
 	kTheTrackNextSampleTime,
 	kTheTrackPreviousKeyTime,
 	kTheTrackPreviousSampleTime,
-	kTheTrackStartTime,
-	kTheTrackStopTime,
 	kTheTrackText,
-	kTheTrackType,
 	kTheTrails,
 	kTheTransitionType,
 	kTheType,


Commit: 88bf79d9429354ab75a6b6cd4b8a6a0cbc94deac
    https://github.com/scummvm/scummvm/commit/88bf79d9429354ab75a6b6cd4b8a6a0cbc94deac
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add D5 bodge for 'type of member'

Changed paths:
    engines/director/castmember/castmember.cpp
    engines/director/types.cpp


diff --git a/engines/director/castmember/castmember.cpp b/engines/director/castmember/castmember.cpp
index 539698ff673..adf356315ad 100644
--- a/engines/director/castmember/castmember.cpp
+++ b/engines/director/castmember/castmember.cpp
@@ -152,8 +152,12 @@ Datum CastMember::getField(int field) {
 		break;
 	case kTheCastType:
 	case kTheType:
+		d = Common::String(castType2str(_type));
+		if (g_director->getVersion() >= 500 && _type == kCastText) {
+			// D5 changes this from "text" to "field"
+			d = Common::String("field");
+		}
 		d.type = SYMBOL;
-		d.u.s = new Common::String(castType2str(_type));
 		break;
 	case kTheFileName:
 		if (castInfo)
diff --git a/engines/director/types.cpp b/engines/director/types.cpp
index 8213af1b447..8d28980b442 100644
--- a/engines/director/types.cpp
+++ b/engines/director/types.cpp
@@ -60,7 +60,7 @@ const char *const castTypes[] = {
 	"movie",
 	"digitalVideo",
 	"script",
-	"RTE",
+	"richText",
 	"???",
 	"transition",
 };


Commit: ffbefea20ca85f05590d1c46a68f3e2de7131c13
    https://github.com/scummvm/scummvm/commit/ffbefea20ca85f05590d1c46a68f3e2de7131c13
Author: Scott Percival (code at moral.net.au)
Date: 2025-02-04T15:24:17+01:00

Commit Message:
DIRECTOR: Add new properties for ScriptCastMember

Changed paths:
    engines/director/castmember/script.cpp
    engines/director/castmember/script.h
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo-the.h


diff --git a/engines/director/castmember/script.cpp b/engines/director/castmember/script.cpp
index 38f56ad2d9d..cd5c5b2b7f1 100644
--- a/engines/director/castmember/script.cpp
+++ b/engines/director/castmember/script.cpp
@@ -21,6 +21,7 @@
 
 #include "director/director.h"
 #include "director/castmember/script.h"
+#include "director/lingo/lingo-the.h"
 
 namespace Director {
 
@@ -70,6 +71,68 @@ ScriptCastMember::ScriptCastMember(Cast *cast, uint16 castId, ScriptCastMember &
 	warning("ScriptCastMember(): Duplicating source %d to target %d! This is unlikely to work properly, as the actual scripts aren't yet copied", source._castId, castId);
 }
 
+bool ScriptCastMember::hasField(int field) {
+	switch (field) {
+	case kTheScriptType:
+		return true;
+	default:
+		break;
+	}
+	return CastMember::hasField(field);
+}
+
+Datum ScriptCastMember::getField(int field) {
+	Datum d;
+
+	switch (field) {
+	case kTheScriptType:
+		switch (_scriptType) {
+		case kMovieScript:
+			d = Common::String("movie");
+			d.type = SYMBOL;
+			break;
+		case kScoreScript:
+			d = Common::String("score");
+			d.type = SYMBOL;
+			break;
+		case kParentScript:
+			d = Common::String("parent");
+			d.type = SYMBOL;
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		d = CastMember::getField(field);
+		break;
+	}
+
+	return d;
+}
+
+bool ScriptCastMember::setField(int field, const Datum &d) {
+	switch (field) {
+	case kTheScriptType:
+		warning("ScriptCastMember::setField(): setting scriptType! This probably isn't going to work as it doesn't recategorize the script.");
+		if (d.type == SYMBOL) {
+			if (d.u.s->equalsIgnoreCase("movie")) {
+				_scriptType = kMovieScript;
+			} else if (d.u.s->equalsIgnoreCase("score")) {
+				_scriptType = kScoreScript;
+			} else if (d.u.s->equalsIgnoreCase("parent")) {
+				_scriptType = kParentScript;
+			}
+		}
+		return true;
+		break;
+	default:
+		break;
+	}
+
+	return CastMember::setField(field, d);
+}
+
 Common::String ScriptCastMember::formatInfo() {
 	return Common::String::format(
 		"scriptType: %s", scriptType2str(_scriptType)
diff --git a/engines/director/castmember/script.h b/engines/director/castmember/script.h
index a9f12a69504..64cee79a4e4 100644
--- a/engines/director/castmember/script.h
+++ b/engines/director/castmember/script.h
@@ -33,6 +33,10 @@ public:
 
 	ScriptType _scriptType;
 
+	bool hasField(int field) override;
+	Datum getField(int field) override;
+	bool setField(int field, const Datum &value) override;
+
 	Common::String formatInfo() override;
 };
 
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 935e2de6714..0d91fe3d15d 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -312,6 +312,9 @@ const TheEntityField fields[] = {
 	// ButtonCastMember fields
 	{ kTheCast,		"buttonType",	kTheButtonType,	500 },//						D5 p
 
+	// ScriptCastMember fields
+	{ kTheCast,		"scriptType",	kTheScriptType,	500 },//						D5 p
+
 	// ShapeCastMember fields
 	{ kTheCast,		"filled",		kTheFilled,		500 },//						D5 p
 	{ kTheCast,		"lineSize",		kTheLineSize,	500 },//						D5 p
diff --git a/engines/director/lingo/lingo-the.h b/engines/director/lingo/lingo-the.h
index bb0605ae185..82a2dccb339 100644
--- a/engines/director/lingo/lingo-the.h
+++ b/engines/director/lingo/lingo-the.h
@@ -252,6 +252,7 @@ enum TheFieldType {
 	kTheScript,
 	kTheScriptNum,
 	kTheScriptText,
+	kTheScriptType,
 	kTheScriptsEnabled,
 	kTheSelectionField,
 	kTheShapeType,




More information about the Scummvm-git-logs mailing list