From fdae9c6030a835a31bcf8bdfdb9c05334aa71648 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sat, 28 Aug 2010 12:03:47 +0000
Subject: [PATCH] Improved character sheet (displays some more resistances and
 betetr char dump)

git-svn-id: http://svn.net-core.org/repos/t-engine4@1090 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engine/utils.lua                         |   8 +-
 game/modules/tome/class/Actor.lua             |   2 +-
 game/modules/tome/class/Player.lua            |   3 +-
 game/modules/tome/class/PlayerDisplay.lua     |   4 +-
 game/modules/tome/data/texts/win.lua          |   5 +
 .../tome/data/zones/grushnak-pride/npcs.lua   |   5 +-
 .../tome/data/zones/high-peak/grids.lua       |   1 +
 game/modules/tome/dialogs/CharacterSheet.lua  | 107 ++++++++++++++----
 ideas/quests.ods                              | Bin 11050 -> 11398 bytes
 9 files changed, 104 insertions(+), 31 deletions(-)

diff --git a/game/engine/utils.lua b/game/engine/utils.lua
index 69bc2f099b..0bec443bec 100644
--- a/game/engine/utils.lua
+++ b/game/engine/utils.lua
@@ -164,6 +164,10 @@ local Pcode = (lpeg.R"af" + lpeg.R"09" + lpeg.R"AF")
 local Pcolorcode = Pcode * Pcode
 local Pcolorcodefull = Pcolorcode * Pcolorcode * Pcolorcode
 
+function string.removeColorCodes(str)
+	return str:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", "")
+end
+
 function string.splitLine(str, max_width, font)
 	local space_w = font:size(" ")
 	local lines = {}
@@ -263,7 +267,7 @@ getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g,
 				oldr, oldg, oldb = r, g, b
 				r, g, b = colors[col].r, colors[col].g, colors[col].b
 			end
-		elseif uid and mo then
+		elseif uid and mo and game.level then
 			uid = tonumber(uid)
 			mo = tonumber(mo)
 			local e = __uids[uid]
@@ -312,7 +316,7 @@ getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y,
 				oldr, oldg, oldb = r, g, b
 				r, g, b = colors[col].r, colors[col].g, colors[col].b
 			end
-		elseif uid and mo then
+		elseif uid and mo and game.level then
 			uid = tonumber(uid)
 			mo = tonumber(mo)
 			local e = __uids[uid]
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 9543a40127..21e1306c6f 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -642,7 +642,7 @@ function _M:die(src)
 	end
 
 	-- Increase vim
-	if src and src:attr("vim_on_death") and not self:attr("undead") then src:incVim(src:attr("vim_on_death")) end
+	if src and src.attr and src:attr("vim_on_death") and not self:attr("undead") then src:incVim(src:attr("vim_on_death")) end
 
 	if src and src.resolveSource and src:resolveSource().player then
 		-- Achievements
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 43611b7075..fca5e77902 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -589,6 +589,7 @@ function _M:useOrbPortal(portal)
 		local ok = false
 		self:restInit(20, "using the portal", "used the poral", function(cnt, max)
 			if cnt > max then ok = true end
+			print("*********** portaling one turn", ok)
 			coroutine.resume(co)
 		end)
 		coroutine.yield()
@@ -598,7 +599,7 @@ function _M:useOrbPortal(portal)
 		end
 		return true
 	end
---	if not wait() then return end
+	if not wait() then return end
 
 	if portal.teleport_level then
 		local x, y = util.findFreeGrid(portal.teleport_level.x, portal.teleport_level.y, 2, true, {[Map.ACTOR]=true})
diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua
index 30967e803c..ab1283c070 100644
--- a/game/modules/tome/class/PlayerDisplay.lua
+++ b/game/modules/tome/class/PlayerDisplay.lua
@@ -104,8 +104,8 @@ function _M:display()
 		self.surface:drawColorStringBlended(self.font, ("#7fffd4#Negative:#ffffff#%d/%d"):format(player:getNegative(), player.max_negative), 0, h, 255, 255, 255) h = h + self.font_h
 	end
 	if player:knowTalent(player.T_VIM_POOL) then
-		self.surface:erase(0xff / 6, 0xcc / 6, 0x80 / 6, 255, self.bars_x, h, self.bars_w, self.font_h)
-		self.surface:erase(0xff / 3, 0xcc / 3, 0x80 / 3, 255, self.bars_x, h, self.bars_w * player:getVim() / player.max_vim, self.font_h)
+		self.surface:erase(0x90 / 6, 0x40 / 6, 0x10 / 6, 255, self.bars_x, h, self.bars_w, self.font_h)
+		self.surface:erase(0x90 / 3, 0x40 / 3, 0x10 / 3, 255, self.bars_x, h, self.bars_w * player:getVim() / player.max_vim, self.font_h)
 		self.surface:drawColorStringBlended(self.font, ("#904010#Vim:     #ffffff#%d/%d"):format(player:getVim(), player.max_vim), 0, h, 255, 255, 255) h = h + self.font_h
 	end
 
diff --git a/game/modules/tome/data/texts/win.lua b/game/modules/tome/data/texts/win.lua
index e6edae43f7..f3c4bd48f0 100644
--- a/game/modules/tome/data/texts/win.lua
+++ b/game/modules/tome/data/texts/win.lua
@@ -34,6 +34,9 @@ end
 if game.player:isQuestStatus("high-peak", engine.Quest.COMPLETED, "gates-of-morning-destroyed") then
 	desc[#desc+1] = ""
 	desc[#desc+1] = "The Gates of Morning have been destroyed and the Sunwall has fallen, the last remnants of the free people in the Far East will surely disminish and soon only orcs will inhabit this land."
+else
+	desc[#desc+1] = ""
+	desc[#desc+1] = "The orc presence in the Far East has greatly been disminished by the loss of their leaders and the destruction of the Istari. The free people of the Sunwall will be able to prosper and thrive on this land."
 end
 
 desc[#desc+1] = ""
@@ -44,4 +47,6 @@ if game.player.winner ~= "self-sacrifice" then
 	desc[#desc+1] = "You may continue playing and enjoy the rest of the world."
 end
 
+game.player.winner_text = desc
+
 return table.concat(desc, "\n")
diff --git a/game/modules/tome/data/zones/grushnak-pride/npcs.lua b/game/modules/tome/data/zones/grushnak-pride/npcs.lua
index 30a88e259c..578dd75220 100644
--- a/game/modules/tome/data/zones/grushnak-pride/npcs.lua
+++ b/game/modules/tome/data/zones/grushnak-pride/npcs.lua
@@ -51,8 +51,9 @@ newEntity{ base="BASE_NPC_ORC_GRUSHNAK", define_as = "GRUSHNAK",
 		{type="armor", subtype="massive", ego_chance=100, autoreq=true},
 		{type="armor", subtype="head", ego_chance=100, autoreq=true},
 		{type="armor", subtype="feet", ego_chance=100, autoreq=true},
-		{type="jewelry", subtype="amulet", ego_chance=100, autoreq=true},
-		{type="jewelry", subtype="ring", ego_chance=100, autoreq=true},
+--		Commented because this can generate rings of invis or amulets of telepathy and drain the life of the boss
+--		{type="jewelry", subtype="amulet", ego_chance=100, autoreq=true},
+--		{type="jewelry", subtype="ring", ego_chance=100, autoreq=true},
 		{type="jewelry", subtype="ring", defined="PRIDE_GLORY", autoreq=true},
 	},
 	resolvers.drops{chance=100, nb=5, {ego_chance=100} },
diff --git a/game/modules/tome/data/zones/high-peak/grids.lua b/game/modules/tome/data/zones/high-peak/grids.lua
index b8e1190ef7..9599b81964 100644
--- a/game/modules/tome/data/zones/high-peak/grids.lua
+++ b/game/modules/tome/data/zones/high-peak/grids.lua
@@ -75,6 +75,7 @@ This one seems to go to an unknown place, seemingly out of this world. You dare
 }
 
 local invocation_close = function(self, who)
+	if not who:hasQuest("high-peak") or who:hasQuest("high-peak"):isCompleted() then return end
 	game.logPlayer(who, "#LIGHT_BLUE#You use the orb on the portal, shutting it down easily.")
 	-- Remove the level spot
 	local spot = game.level:pickSpot{type="portal", subtype=self.summon}
diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua
index 1565624384..5744d85b56 100644
--- a/game/modules/tome/dialogs/CharacterSheet.lua
+++ b/game/modules/tome/dialogs/CharacterSheet.lua
@@ -64,8 +64,14 @@ function _M:drawDialog(s)
 	if game.player:knowTalent(game.player.T_MANA_POOL) then
 		s:drawColorStringBlended(self.font, ("#7fffd4#Mana:    #00ff00#%d/%d"):format(game.player:getMana(), game.player.max_mana), w, h, 255, 255, 255) h = h + self.font_h
 	end
-	if game.player:knowTalent(game.player.T_SOUL_POOL) then
-		s:drawColorStringBlended(self.font, ("#777777#Soul:    #00ff00#%d/%d"):format(game.player:getSoul(), game.player.max_soul), w, h, 255, 255, 255) h = h + self.font_h
+	if game.player:knowTalent(game.player.T_POSITIVE_POOL) then
+		s:drawColorStringBlended(self.font, ("#7fffd4#Positive:#00ff00#%d/%d"):format(game.player:getPositive(), game.player.max_positive), w, h, 255, 255, 255) h = h + self.font_h
+	end
+	if game.player:knowTalent(game.player.T_NEGATIVE_POOL) then
+		s:drawColorStringBlended(self.font, ("#7fffd4#Negative:#00ff00#%d/%d"):format(game.player:getNegative(), game.player.max_negative), w, h, 255, 255, 255) h = h + self.font_h
+	end
+	if game.player:knowTalent(game.player.T_VIM_POOL) then
+		s:drawColorStringBlended(self.font, ("#904010#Vim:     #00ff00#%d/%d"):format(game.player:getVim(), game.player.max_vim), w, h, 255, 255, 255) h = h + self.font_h
 	end
 	if game.player:knowTalent(game.player.T_EQUILIBRIUM_POOL) then
 		s:drawColorStringBlended(self.font, ("#00ff74#Equi:    #00ff00#%d"):format(game.player:getEquilibrium()), w, h, 255, 255, 255) h = h + self.font_h
@@ -144,6 +150,20 @@ function _M:drawDialog(s)
 		end
 	end
 
+	immune_type = "poison_immune" immune_name = "Poison Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "cut_immune" immune_name = "Bleed Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "confusion_immune" immune_name = "Confusion Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "blind_immune" immune_name = "Blind Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "silence_immune" immune_name = "Silence Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "disarm_immune" immune_name = "Disarm Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "pin_immune" immune_name = "Pinning Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "stun_immune" immune_name = "Stun Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "fear_immune" immune_name = "Fear Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "knockback_immune" immune_name = "Knockback Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "stone_immune" immune_name = "Stoning Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "instakill_immune" immune_name = "Instadeath Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+	immune_type = "teleport_immune" immune_name = "Teleport Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end
+
 	h = 0
 	w = 600
 	s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Current effects:", w, h, 255, 255, 255) h = h + self.font_h
@@ -167,8 +187,8 @@ function _M:dump()
 	local file = "/character-dumps/"..(game.player.name:gsub("[^a-zA-Z0-9_-.]", "_")).."-"..os.date("%Y%m%d-%H%M%S")..".txt"
 	local fff = fs.open(file, "w")
 	local labelwidth = 17
-	local nl = function(s) fff:write(s or "") fff:write("\n") end
-	local nnl = function(s) fff:write(s or "") end
+	local nl = function(s) s = s or "" fff:write(s:removeColorCodes()) fff:write("\n") end
+	local nnl = function(s) s = s or "" fff:write(s:removeColorCodes()) end
 	--prepare label and value
 	local makelabel = function(s,r) while s:len() < labelwidth do s = s.." " end return ("%s: %s"):format(s, r) end
 
@@ -191,7 +211,7 @@ function _M:dump()
 	nnl(("%-32s"):format(makelabel("Exp", ("%d%%"):format(100 * cur_exp / max_exp))))
 	nl(("CUN:  %d"):format(game.player:getCun()))
 
-	 nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(game.player.money))))
+	nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(game.player.money))))
 	nl(("CON:  %d"):format(game.player:getCon()))
 
 	 -- All weapons in main hands
@@ -232,9 +252,21 @@ function _M:dump()
 		nl()
 	end
 	nnl(("%-32s"):format(strings[4]))
-	if game.player:knowTalent(game.player.T_SOUL_POOL) then
-		nl(makelabel("Soul", ("    %d/%d"):format(game.player:getSoul(), game.player.max_soul)))
-	 else
+	if game.player:knowTalent(game.player.T_POSITIVE_POOL) then
+		nl(makelabel("Positive", ("    %d/%d"):format(game.player:getPositive(), game.player.max_positive)))
+	else
+		nl()
+	end
+	nnl(("%-32s"):format(strings[4]))
+	if game.player:knowTalent(game.player.T_NEGATIVE_POOL) then
+		nl(makelabel("Negative", ("    %d/%d"):format(game.player:getNegative(), game.player.max_negative)))
+	else
+		nl()
+	end
+	nnl(("%-32s"):format(strings[4]))
+	if game.player:knowTalent(game.player.T_VIM_POOL) then
+		nl(makelabel("Vim", ("    %d/%d"):format(game.player:getVim(), game.player.max_vim)))
+	else
 		nl()
 	end
 	nnl(("%-32s"):format(strings[5]))
@@ -294,6 +326,20 @@ function _M:dump()
 		end
 	end
 
+	immune_type = "poison_immune" immune_name = "Poison Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "cut_immune" immune_name = "Bleed Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "confusion_immune" immune_name = "Confusion Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "blind_immune" immune_name = "Blind Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "silence_immune" immune_name = "Silence Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "disarm_immune" immune_name = "Disarm Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "pin_immune" immune_name = "Pinning Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "stun_immune" immune_name = "Stun Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "fear_immune" immune_name = "Fear Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "knockback_immune" immune_name = "Knockback Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "stone_immune" immune_name = "Stoning Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "instakill_immune" immune_name = "Instadeath Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+	immune_type = "teleport_immune" immune_name = "Teleport Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end
+
 	nl()
 	local most_kill, most_kill_max = "none", 0
 	local total_kill = 0
@@ -304,6 +350,15 @@ function _M:dump()
 	nl(("Number of NPC killed: %s"):format(total_kill))
 	nl(("Most killed NPC: %s (%d)"):format(most_kill, most_kill_max))
 
+	if self.actor.winner then
+		nl()
+		nl("  [Winner!]")
+		nl()
+		for i, line in ipairs(self.actor.winner_text) do
+			nl(("%s"):format(line:removeColorCodes()))
+		end
+	end
+
 	-- Talents
 	nl()
 	nl("  [Talents Chart]")
@@ -321,7 +376,7 @@ function _M:dump()
 				for j, t in ipairs(tt.talents) do
 					if not t.hide then
 						local typename = "class"
-						if t.skill then typename = "generic" end
+						if t.generic then typename = "generic" end
 						local skillname = ("    %s (%s)"):format(t.name, typename)
 						nl(("%-37s %d/%d"):format(skillname, self.actor:getTalentLevelRaw(t.id), t.points))
 					end
@@ -353,14 +408,14 @@ function _M:dump()
 	local first = true
 	for id, q in pairs(self.actor.quests or {}) do
 		if q:isEnded() then
-			 if first then
-					 nl()
-					 nl("  [Completed Quests]")
-					 nl()
-					 first=false
-			 end
-			  nl(" -- ".. q.name)
-			  nl(q:desc(self.actor):gsub("#.-#", "   "))
+			if first then
+					nl()
+					nl("  [Completed Quests]")
+					nl()
+					first=false
+			end
+			nl(" -- ".. q.name)
+			nl(q:desc(self.actor):gsub("#.-#", "   "))
 		end
 	end
 
@@ -368,13 +423,13 @@ function _M:dump()
 	for id, q in pairs(self.actor.quests or {}) do
 		if not q:isEnded() then
 			if first then
-					 first=false
-					 nl()
+					first=false
+					nl()
 					nl("  [Active Quests]")
-					 nl()
+					nl()
 				end
-			  nl(" -- ".. q.name)
-			  nl(q:desc(self.actor):gsub("#.-#", "   "))
+			nl(" -- ".. q.name)
+			nl(q:desc(self.actor):gsub("#.-#", "   "))
 		end
 	end
 
@@ -405,9 +460,15 @@ function _M:dump()
 	nl()
 	nl("  [Player Achievements]")
 	nl()
+	local achs = {}
 	for id, data in pairs(self.actor.achievements or {}) do
 		local a = world:getAchievementFromId(id)
-		nl(("%s Was Achieved for %s At %s"):format(a.name,a.desc,data.when))
+		achs[#achs+1] = {id=id, data=data, name=a.name}
+	end
+	table.sort(achs, function(a, b) return a.name < b.name end)
+	for i, d in ipairs(achs) do
+		local a = world:getAchievementFromId(d.id)
+		nl(("'%s' was wchieved for %s At %s"):format(a.name, a.desc, d.data.when))
 	end
 
 	nl()
diff --git a/ideas/quests.ods b/ideas/quests.ods
index f25186fb83d30b7eec9d446a221eb99835a12174..629365d1c26c7860d211a1c30782846c8a0f47d9 100644
GIT binary patch
delta 8219
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
MVL}c9|M~2H0PI_kb^rhX

delta 7870
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
URyH#D40?zm8{-QG#=lAb4>hQ#BLDyZ

-- 
GitLab