Removed 'release mode' and love.releaseerrhand, and added love.filesystem.isFused (resolves issue #579).

Games which are fused (either via appending the .love to the executable or with --fused) automatically have the changes which previously only applied to fused games in release mode.
This commit is contained in:
Alex Szpakowski
2013-08-05 15:02:50 -03:00
parent 4443284a73
commit fc3affb9b9
6 changed files with 36 additions and 216 deletions
+12 -14
View File
@@ -35,11 +35,9 @@ namespace physfs
{
Filesystem::Filesystem()
: open_count(0)
, buffer(0)
, initialized(false)
, release(false)
, releaseSet(false)
: initialized(false)
, fused(false)
, fusedSet(false)
{
}
@@ -61,19 +59,19 @@ void Filesystem::init(const char *arg0)
initialized = true;
}
void Filesystem::setRelease(bool release)
void Filesystem::setFused(bool fused)
{
if (releaseSet)
if (fusedSet)
return;
this->release = release;
releaseSet = true;
this->fused = fused;
fusedSet = true;
}
bool Filesystem::isRelease() const
bool Filesystem::isFused() const
{
if (!releaseSet)
if (!fusedSet)
return false;
return release;
return fused;
}
bool Filesystem::setIdentity(const char *ident, SearchOrder searchorder)
@@ -91,7 +89,7 @@ bool Filesystem::setIdentity(const char *ident, SearchOrder searchorder)
// Generate the full path to the game save folder.
save_path_full = std::string(getAppdataDirectory()) + std::string(LOVE_PATH_SEPARATOR);
if (release)
if (fused)
save_path_full += std::string(LOVE_APPDATA_PREFIX) + save_identity;
else
save_path_full += save_path_relative;
@@ -155,7 +153,7 @@ bool Filesystem::setupWriteDirectory()
// Create the save folder. (We're now "at" %APPDATA%).
bool success = false;
if (release)
if (fused)
success = mkdir(save_identity.c_str());
else
success = mkdir(save_path_relative.c_str());
+4 -10
View File
@@ -93,8 +93,8 @@ public:
void init(const char *arg0);
void setRelease(bool release);
bool isRelease() const;
void setFused(bool fused);
bool isFused() const;
/**
* This sets up the save directory. If the
@@ -280,12 +280,6 @@ public:
private:
// Counts open files.
int open_count;
// Pointer used for file reads.
char *buffer;
// Contains the current working directory (UTF8).
std::string cwd;
@@ -309,8 +303,8 @@ private:
// Allow saving outside of the LOVE_APPDATA_FOLDER
// for release 'builds'
bool release;
bool releaseSet;
bool fused;
bool fusedSet;
static StringMap<SearchOrder, SEARCH_ORDER_MAX_ENUM>::Entry orderEntries[];
static StringMap<SearchOrder, SEARCH_ORDER_MAX_ENUM> orders;
@@ -65,14 +65,20 @@ int w_init(lua_State *L)
return 0;
}
int w_setRelease(lua_State *L)
int w_setFused(lua_State *L)
{
// no error checking needed, everything, even nothing
// can be converted to a boolean
instance->setRelease(luax_toboolean(L, 1));
instance->setFused(luax_toboolean(L, 1));
return 0;
}
int w_isFused(lua_State *L)
{
luax_pushboolean(L, instance->isFused());
return 1;
}
int w_setIdentity(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
@@ -541,7 +547,7 @@ int extloader(lua_State *L)
tokenized_name += library_extension();
void *handle = SDL_LoadObject((std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name).c_str());
if (!handle && instance->isRelease())
if (!handle && instance->isFused())
handle = SDL_LoadObject((std::string(instance->getSaveDirectory()) + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
if (!handle)
@@ -569,7 +575,8 @@ int extloader(lua_State *L)
static const luaL_Reg functions[] =
{
{ "init", w_init },
{ "setRelease", w_setRelease },
{ "setFused", w_setFused },
{ "isFused", w_isFused },
{ "setIdentity", w_setIdentity },
{ "getIdentity", w_getIdentity },
{ "setSource", w_setSource },
@@ -38,7 +38,8 @@ namespace physfs
bool hack_setupWriteDirectory();
int w_init(lua_State *L);
int w_setRelease(lua_State *L);
int w_setFused(lua_State *L);
int w_isFused(lua_State *L);
int w_setIdentity(lua_State *L);
int w_getIdentity(lua_State *L);
int w_setSource(lua_State *L);
+2 -69
View File
@@ -295,7 +295,6 @@ function love.init()
console = false, -- Only relevant for windows.
identity = false,
identityorder = "first",
release = false,
}
-- If config file exists, load it and allow it to update config table.
@@ -313,14 +312,6 @@ function love.init()
end
end
if c.release then
love._release = {
title = c.title ~= "Untitled" and c.title or nil,
author = c.author ~= "Unnamed" and c.author or nil,
url = c.url
}
end
if love.arg.options.console.set then
c.console = true
end
@@ -381,7 +372,7 @@ function love.init()
end
if love.filesystem then
love.filesystem.setRelease(c.release and is_fused_game)
love.filesystem.setFused(is_fused_game)
love.filesystem.setIdentity(c.identity or love.filesystem.getIdentity(), c.identityorder)
if love.filesystem.exists("main.lua") then
require("main")
@@ -1515,66 +1506,8 @@ function love.errhand(msg)
end
function love.releaseerrhand(msg)
print("An error has occured, the game has been stopped.")
if not love.window or not love.graphics or not love.event then
return
end
if not love.graphics.isCreated() or not love.window.isCreated() then
if not pcall(love.window.setMode, 800, 600) then
return
end
end
love.graphics.setCanvas()
love.graphics.setShader()
-- Load.
if love.audio then love.audio.stop() end
love.graphics.reset()
love.graphics.setBackgroundColor(89, 157, 220)
local font = love.graphics.newFont(14)
love.graphics.setFont(font)
love.graphics.setColor(255, 255, 255, 255)
love.graphics.clear()
love.graphics.origin()
local err = {}
p = string.format("An error has occured that caused %s to stop.\nYou can notify %s about this%s.", love._release.title or "this game", love._release.author or "the author", love._release.url and " at " .. love._release.url or "")
local function draw()
love.graphics.clear()
love.graphics.printf(p, 70, 70, love.graphics.getWidth() - 70)
love.graphics.present()
end
while true do
love.event.pump()
for e, a, b, c in love.event.poll() do
if e == "quit" then
return
end
if e == "keypressed" and a == "escape" then
return
end
end
draw()
if love.timer then
love.timer.sleep(0.1)
end
end
end
local function deferErrhand(...)
local handler = ((love._release and love.releaseerrhand) or love.errhand or error_printer)
local handler = love.errhand or error_printer
return handler(...)
end
+5 -118
View File
@@ -511,7 +511,6 @@ const unsigned char boot_lua[] =
0x2c, 0x0a,
0x09, 0x09, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20,
0x22, 0x66, 0x69, 0x72, 0x73, 0x74, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x0a,
0x09, 0x7d, 0x0a,
0x09, 0x2d, 0x2d, 0x20, 0x49, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65,
0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x2c, 0x20, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x69, 0x74, 0x20, 0x61,
@@ -541,18 +540,6 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x3d, 0x20,
0x7b, 0x0a,
0x09, 0x09, 0x09, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65,
0x20, 0x7e, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64,
0x20, 0x63, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x20, 0x7e, 0x3d, 0x20, 0x22, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e,
0x64, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x75, 0x72, 0x6c, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x75, 0x72, 0x6c, 0x0a,
0x09, 0x09, 0x7d, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x0a,
@@ -651,9 +638,8 @@ const unsigned char boot_lua[] =
0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65,
0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e,
0x73, 0x65, 0x74, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x28, 0x63, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61,
0x73, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x67, 0x61,
0x6d, 0x65, 0x29, 0x0a,
0x73, 0x65, 0x74, 0x46, 0x75, 0x73, 0x65, 0x64, 0x28, 0x69, 0x73, 0x5f, 0x66, 0x75, 0x73, 0x65, 0x64, 0x5f,
0x67, 0x61, 0x6d, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e,
0x73, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x28, 0x63, 0x2e, 0x69, 0x64, 0x65, 0x6e,
0x74, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73,
@@ -5155,110 +5141,11 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x65, 0x6e, 0x64, 0x0a,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x65,
0x61, 0x73, 0x65, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x0a,
0x09, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x28, 0x22, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68,
0x61, 0x73, 0x20, 0x6f, 0x63, 0x63, 0x75, 0x72, 0x65, 0x64, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x67, 0x61,
0x6d, 0x65, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x70, 0x65,
0x64, 0x2e, 0x22, 0x29, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70,
0x68, 0x69, 0x63, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65,
0x76, 0x65, 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68,
0x69, 0x63, 0x73, 0x2e, 0x69, 0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x6f, 0x72,
0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x69,
0x73, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6c, 0x6f, 0x76,
0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x2c, 0x20,
0x38, 0x30, 0x30, 0x2c, 0x20, 0x36, 0x30, 0x30, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x28, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x29, 0x0a,
0x09, 0x2d, 0x2d, 0x20, 0x4c, 0x6f, 0x61, 0x64, 0x2e, 0x0a,
0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x74, 0x68, 0x65,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x28,
0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x72, 0x65, 0x73,
0x65, 0x74, 0x28, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
0x42, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x38, 0x39,
0x2c, 0x20, 0x31, 0x35, 0x37, 0x2c, 0x20, 0x32, 0x32, 0x30, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65,
0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6e, 0x65, 0x77, 0x46, 0x6f, 0x6e, 0x74, 0x28,
0x31, 0x34, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
0x46, 0x6f, 0x6e, 0x74, 0x28, 0x66, 0x6f, 0x6e, 0x74, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x74,
0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35,
0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c, 0x65,
0x61, 0x72, 0x28, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x6f, 0x72, 0x69,
0x67, 0x69, 0x6e, 0x28, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x0a,
0x09, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,
0x28, 0x22, 0x41, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x68, 0x61, 0x73, 0x20, 0x6f, 0x63, 0x63,
0x75, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x63, 0x61, 0x75, 0x73, 0x65, 0x64, 0x20, 0x25,
0x73, 0x20, 0x74, 0x6f, 0x20, 0x73, 0x74, 0x6f, 0x70, 0x2e, 0x5c, 0x6e, 0x59, 0x6f, 0x75, 0x20, 0x63, 0x61,
0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x20, 0x25, 0x73, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20,
0x74, 0x68, 0x69, 0x73, 0x25, 0x73, 0x2e, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65,
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74, 0x68,
0x69, 0x73, 0x20, 0x67, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65,
0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x74,
0x68, 0x65, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x22, 0x2c, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f,
0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x75, 0x72, 0x6c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x22, 0x20,
0x61, 0x74, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65,
0x61, 0x73, 0x65, 0x2e, 0x75, 0x72, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x22, 0x22, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72,
0x61, 0x77, 0x28, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x63, 0x6c,
0x65, 0x61, 0x72, 0x28, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72,
0x69, 0x6e, 0x74, 0x66, 0x28, 0x70, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x37, 0x30, 0x2c, 0x20, 0x6c, 0x6f,
0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x57, 0x69, 0x64,
0x74, 0x68, 0x28, 0x29, 0x20, 0x2d, 0x20, 0x37, 0x30, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72,
0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x74, 0x72, 0x75, 0x65, 0x20, 0x64, 0x6f, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70, 0x28,
0x29, 0x0a,
0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x65, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63, 0x20, 0x69,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28,
0x29, 0x20, 0x64, 0x6f, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x6b, 0x65, 0x79, 0x70, 0x72, 0x65,
0x73, 0x73, 0x65, 0x64, 0x22, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x65, 0x73,
0x63, 0x61, 0x70, 0x65, 0x22, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68,
0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65,
0x70, 0x28, 0x30, 0x2e, 0x31, 0x29, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x65, 0x6e, 0x64, 0x0a,
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x66,
0x65, 0x72, 0x45, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x28,
0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20, 0x61, 0x6e, 0x64,
0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x65, 0x72, 0x72, 0x68, 0x61,
0x6e, 0x64, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e,
0x64, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72,
0x29, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c,
0x6f, 0x76, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x0a,
0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x28, 0x2e, 0x2e,
0x2e, 0x29, 0x0a,
0x65, 0x6e, 0x64, 0x0a,