From: Ketmar Dark Date: Fri, 8 Sep 2017 20:29:10 +0000 (+0300) Subject: save/load fixes X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=dd969f579db2bf70f6ddfcb5d377b2b95b994a6e;p=d2df-sdl.git save/load fixes plus one very experimental feature, do not touch! --- diff --git a/src/game/Doom2DF.dpr b/src/game/Doom2DF.dpr index a47b72d..806032d 100644 --- a/src/game/Doom2DF.dpr +++ b/src/game/Doom2DF.dpr @@ -101,6 +101,7 @@ uses idpool in '../shared/idpool.pas', xparser in '../shared/xparser.pas', xdynrec in '../shared/xdynrec.pas', + exoma in '../shared/exoma.pas', BinEditor in '../shared/BinEditor.pas', envvars in '../shared/envvars.pas', g_panel in 'g_panel.pas', diff --git a/src/game/g_map.pas b/src/game/g_map.pas index e2612f4..c395dab 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -1338,22 +1338,9 @@ begin trigPanelGUID := atrigpanid; //trigShotPanelId := ashotpanid; //Data.Default := Trigger.DATA; - if (Trigger.trigRec = nil) then - begin - trigDataRec := nil; - //HACK! - if (TriggerType <> TRIGGER_SECRET) then - begin - e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [TriggerType], MSG_WARNING); - end; - end - else - begin - trigDataRec := Trigger.trigRec.clone(nil); - end; end; - result := Integer(g_Triggers_Create(_trigger)); + result := Integer(g_Triggers_Create(_trigger, Trigger)); end; procedure CreateMonster(monster: TDynRecord); @@ -3083,14 +3070,12 @@ var var PAMem: TBinMemoryWriter; pan: TPanel; - count: Integer; begin // Ñîçäàåì íîâûé ñïèñîê ñîõðàíÿåìûõ ïàíåëåé PAMem := TBinMemoryWriter.Create((Length(panByGUID)+1) * 40); // Ñîõðàíÿåì ïàíåëè - count := Length(panByGUID); - Mem.WriteInt(count); + //Mem.WriteInt(Length(panByGUID)); for pan in panByGUID do pan.SaveState(PAMem); // Ñîõðàíÿåì ýòîò ñïèñîê ïàíåëåé @@ -3174,15 +3159,16 @@ var var PAMem: TBinMemoryReader; pan: TPanel; - count: LongInt; + //count: LongInt; begin // Çàãðóæàåì òåêóùèé ñïèñîê ïàíåëåé PAMem := TBinMemoryReader.Create(); PAMem.LoadFromMemory(Mem); // Çàãðóæàåì ïàíåëè - PAMem.ReadInt(count); - if (count <> Length(panByGUID)) then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: invalid number of panels'); + //PAMem.ReadInt(count); + //if (count <> Length(panByGUID)) then raise EBinSizeError.Create('g_Map_LoadState: LoadPanelArray: invalid number of panels'); + //if (count <> Length(panByGUID)) then raise EBinSizeError.Create(Format('g_Map_LoadState: LoadPanelArray: invalid number of panels (%d : %d)', [count, Length(panByGUID)])); for pan in panByGUID do begin pan.LoadState(PAMem); diff --git a/src/game/g_panel.pas b/src/game/g_panel.pas index 563beff..07fe2d6 100644 --- a/src/game/g_panel.pas +++ b/src/game/g_panel.pas @@ -1009,10 +1009,11 @@ begin Result := Result + 100; end; + const PAN_SAVE_VERSION = 1; -procedure TPanel.SaveState(Var Mem: TBinMemoryWriter); +procedure TPanel.SaveState (var Mem: TBinMemoryWriter); var sig: DWORD; anim: Boolean; @@ -1020,35 +1021,35 @@ var begin if (Mem = nil) then exit; -// Ñèãíàòóðà ïàíåëè: + // Ñèãíàòóðà ïàíåëè sig := PANEL_SIGNATURE; // 'PANL' Mem.WriteDWORD(sig); ver := PAN_SAVE_VERSION; Mem.WriteByte(ver); -// Îòêðûòà/çàêðûòà, åñëè äâåðü: + // Îòêðûòà/çàêðûòà, åñëè äâåðü Mem.WriteBoolean(FEnabled); -// Íàïðàâëåíèå ëèôòà, åñëè ëèôò: + // Íàïðàâëåíèå ëèôòà, åñëè ëèôò Mem.WriteByte(FLiftType); -// Íîìåð òåêóùåé òåêñòóðû: + // Íîìåð òåêóùåé òåêñòóðû Mem.WriteInt(FCurTexture); -// Êîîðäû + // Êîîðäû Mem.WriteInt(FX); Mem.WriteInt(FY); Mem.WriteWord(FWidth); Mem.WriteWord(FHeight); -// Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà: + // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà if (FCurTexture >= 0) and (FTextureIDs[FCurTexture].Anim) then - begin - Assert(FTextureIDs[FCurTexture].AnTex <> nil, - 'TPanel.SaveState: No animation object'); - anim := True; - end + begin + assert(FTextureIDs[FCurTexture].AnTex <> nil, 'TPanel.SaveState: No animation object'); + anim := True; + end else + begin anim := False; + end; Mem.WriteBoolean(anim); -// Åñëè äà - ñîõðàíÿåì àíèìàöèþ: - if anim then - FTextureIDs[FCurTexture].AnTex.SaveState(Mem); + // Åñëè äà - ñîõðàíÿåì àíèìàöèþ + if anim then FTextureIDs[FCurTexture].AnTex.SaveState(Mem); // moving platform state Mem.WriteInt(mMovingSpeed.X); @@ -1062,6 +1063,7 @@ begin Mem.WriteInt(mSizeSpeed.h); Mem.WriteInt(mSizeEnd.w); Mem.WriteInt(mSizeEnd.h); + Mem.WriteBoolean(mMovingActive); Mem.WriteBoolean(mMoveOnce); @@ -1069,37 +1071,35 @@ begin Mem.WriteInt(mEndSizeTrig); end; -procedure TPanel.LoadState(var Mem: TBinMemoryReader); + +procedure TPanel.LoadState (var Mem: TBinMemoryReader); var sig: DWORD; anim: Boolean; ver: Byte; - //ox, oy: Integer; begin if (Mem = nil) then exit; -// Ñèãíàòóðà ïàíåëè: + // Ñèãíàòóðà ïàíåëè Mem.ReadDWORD(sig); if (sig <> PANEL_SIGNATURE) then raise EBinSizeError.Create('TPanel.LoadState: wrong panel signature'); // 'PANL' Mem.ReadByte(ver); if (ver <> PAN_SAVE_VERSION) then raise EBinSizeError.Create('TPanel.LoadState: invalid panel version'); -// Îòêðûòà/çàêðûòà, åñëè äâåðü: + // Îòêðûòà/çàêðûòà, åñëè äâåðü Mem.ReadBoolean(FEnabled); -// Íàïðàâëåíèå ëèôòà, åñëè ëèôò: + // Íàïðàâëåíèå ëèôòà, åñëè ëèôò Mem.ReadByte(FLiftType); -// Íîìåð òåêóùåé òåêñòóðû: + // Íîìåð òåêóùåé òåêñòóðû Mem.ReadInt(FCurTexture); -// Êîîðäû - //ox := FX; - //oy := FY; + // Êîîðäû Mem.ReadInt(FX); Mem.ReadInt(FY); Mem.ReadWord(FWidth); Mem.ReadWord(FHeight); //e_LogWritefln('panel %s(%s): old=(%s,%s); new=(%s,%s); delta=(%s,%s)', [arrIdx, proxyId, ox, oy, FX, FY, FX-ox, FY-oy]); -// Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà: + // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà Mem.ReadBoolean(anim); -// Åñëè äà - çàãðóæàåì àíèìàöèþ: + // Åñëè äà - çàãðóæàåì àíèìàöèþ if anim then begin Assert((FCurTexture >= 0) and @@ -1116,10 +1116,12 @@ begin Mem.ReadInt(mMovingStart.Y); Mem.ReadInt(mMovingEnd.X); Mem.ReadInt(mMovingEnd.Y); + Mem.ReadInt(mSizeSpeed.w); Mem.ReadInt(mSizeSpeed.h); Mem.ReadInt(mSizeEnd.w); Mem.ReadInt(mSizeEnd.h); + Mem.ReadBoolean(mMovingActive); Mem.ReadBoolean(mMoveOnce); diff --git a/src/game/g_triggers.pas b/src/game/g_triggers.pas index fab30ec..e49a4ef 100644 --- a/src/game/g_triggers.pas +++ b/src/game/g_triggers.pas @@ -19,14 +19,18 @@ unit g_triggers; interface uses + Variants, MAPDEF, e_graphics, g_basic, g_sound, - BinEditor, xdynrec; + BinEditor, xdynrec, hashtable, exoma; type + THashStrVariant = specialize THashBase; + TActivator = record UID: Word; TimeOut: Word; end; + PTrigger = ^TTrigger; TTrigger = record public @@ -67,6 +71,9 @@ type trigPanelGUID: Integer; trigDataRec: TDynRecord; // triggerdata; owned by trigger (cloned) + exoInit, exoThink, exoCheck, exoAction: TExprBase; + + userVars: THashStrVariant; {$INCLUDE ../shared/mapdef_tgc_def.inc} @@ -74,7 +81,7 @@ type function trigCenter (): TDFPoint; inline; end; -function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD; +function g_Triggers_Create(Trigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; procedure g_Triggers_Update(); procedure g_Triggers_Press(ID: DWORD; ActivateType: Byte; ActivateUID: Word = 0); function g_Triggers_PressR(X, Y: Integer; Width, Height: Word; UID: Word; @@ -110,6 +117,101 @@ const {$INCLUDE ../shared/mapdef_tgc_impl.inc} + +// ////////////////////////////////////////////////////////////////////////// // +type + TTrigScope = class(TExprScope) + private + plrprops: TPropHash; + monsprops: TPropHash; + platprops: TPropHash; + + public + me: PTrigger; + + public + constructor Create (); + destructor Destroy (); override; + + function getObj (const aname: AnsiString): TObject; override; + function getField (obj: TObject; const afldname: AnsiString): Variant; override; + procedure setField (obj: TObject; const afldname: AnsiString; var aval: Variant); override; + end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TTrigScope.Create (); +begin + plrprops := TPropHash.Create(TPlayer); + monsprops := TPropHash.Create(TMonster); + platprops := TPropHash.Create(TPanel); + me := nil; +end; + + +destructor TTrigScope.Destroy (); +begin + platprops.Free(); + monsprops.Free(); + plrprops.Free(); + inherited; +end; + + +function TTrigScope.getObj (const aname: AnsiString): TObject; +begin + if (aname = 'player') then result := gPlayers[0] //FIXME + else if (aname = 'self') or (aname = 'this') then result := TObject(Pointer(PtrUInt(1))) + else result := inherited getObj(aname); +end; + + +function TTrigScope.getField (obj: TObject; const afldname: AnsiString): Variant; +begin + if (obj = gPlayers[0]) then + begin + if plrprops.get(obj, afldname, result) then exit; + end + else if (obj = TObject(Pointer(PtrUInt(1)))) then + begin + if (me <> nil) and (me.userVars <> nil) then + begin + if me.userVars.get(afldname, result) then exit; + end; + end; + result := inherited getField(obj, afldname); +end; + + +procedure TTrigScope.setField (obj: TObject; const afldname: AnsiString; var aval: Variant); +begin + if (obj = gPlayers[0]) then + begin + if plrprops.put(obj, afldname, aval) then exit; + end + else if (obj = TObject(Pointer(PtrUInt(1)))) then + begin + if (me <> nil) then + begin + if (Length(afldname) > 4) and (afldname[1] = 'u') and (afldname[2] = 's') and + (afldname[3] = 'e') and (afldname[4] = 'r') then + begin + if (me.userVars = nil) then me.userVars := THashStrVariant.Create(hsihash, hsiequ); + me.userVars.put(afldname, aval); + exit; + end; + end; + end; + inherited setField(obj, afldname, aval); +end; + + +// ////////////////////////////////////////////////////////////////////////// // +var + tgscope: TTrigScope = nil; + + +// ////////////////////////////////////////////////////////////////////////// // function TTrigger.trigCenter (): TDFPoint; inline; begin result := TDFPoint.Create(x+width div 2, y+height div 2); @@ -118,23 +220,27 @@ end; function FindTrigger (): DWORD; var - i: Integer; + i, olen: Integer; begin - for i := 0 to High(gTriggers) do + olen := Length(gTriggers); + + for i := 0 to olen-1 do begin if gTriggers[i].TriggerType = TRIGGER_NONE then begin result := i; exit; end; end; - if (gTriggers = nil) then - begin - SetLength(gTriggers, 8); - result := 0; - end - else + SetLength(gTriggers, olen+8); + result := olen; + + for i := result to High(gTriggers) do begin - result := Length(gTriggers); - SetLength(gTriggers, result+8); - for i := result to High(gTriggers) do gTriggers[i].TriggerType := TRIGGER_NONE; + gTriggers[i].TriggerType := TRIGGER_NONE; + gTriggers[i].trigDataRec := nil; + gTriggers[i].exoInit := nil; + gTriggers[i].exoThink := nil; + gTriggers[i].exoCheck := nil; + gTriggers[i].exoAction := nil; + gTriggers[i].userVars := nil; end; end; @@ -1065,18 +1171,49 @@ var end; end; +var + tvval: Variant; begin result := false; if g_Game_IsClient then exit; if not Trigger.Enabled then exit; if (Trigger.TimeOut <> 0) and (actType <> ACTIVATE_CUSTOM) then exit; - if gLMSRespawn = LMS_RESPAWN_WARMUP then exit; + if (gLMSRespawn = LMS_RESPAWN_WARMUP) then exit; + + if (Trigger.exoCheck <> nil) then + begin + //conwritefln('exocheck: [%s]', [Trigger.exoCheck.toString()]); + try + tgscope.me := @Trigger; + tvval := Trigger.exoCheck.value(tgscope); + tgscope.me := nil; + if not Boolean(tvval) then exit; + except + tgscope.me := nil; + conwritefln('trigger exocheck error: %s', [Trigger.exoCheck.toString()]); + exit; + end; + end; animonce := False; coolDown := (actType <> 0); + if (Trigger.exoAction <> nil) then + begin + //conwritefln('exoactivate: [%s]', [Trigger.exoAction.toString()]); + try + tgscope.me := @Trigger; + Trigger.exoAction.value(tgscope); + tgscope.me := nil; + except + tgscope.me := nil; + conwritefln('trigger exoactivate error: %s', [Trigger.exoAction.toString()]); + exit; + end; + end; + with Trigger do begin case TriggerType of @@ -2139,10 +2276,11 @@ begin triggers := gCurrentMap['trigger']; if (triggers = nil) then raise Exception.Create('LOAD: map has no triggers'); if (mapidx < 0) or (mapidx >= triggers.count) then raise Exception.Create('LOAD: invalid map trigger index'); - Trigger.trigDataRec := triggers.itemAt[mapidx]; - if (Trigger.trigDataRec = nil) then raise Exception.Create('LOAD: internal error in trigger loader'); - Trigger.mapId := Trigger.trigDataRec.id; + //Trigger.trigDataRec := triggers.itemAt[mapidx]; + //if (Trigger.trigDataRec = nil) then raise Exception.Create('LOAD: internal error in trigger loader'); + //Trigger.mapId := Trigger.trigDataRec.id; Trigger.mapIndex := mapidx; + { if (Trigger.trigDataRec.trigRec <> nil) then begin Trigger.trigDataRec := Trigger.trigDataRec.trigRec.clone(nil); @@ -2151,16 +2289,19 @@ begin begin Trigger.trigDataRec := nil; end; - result := g_Triggers_Create(Trigger, arridx); + } + result := g_Triggers_Create(Trigger, triggers.itemAt[mapidx], arridx); end; -function g_Triggers_Create(Trigger: TTrigger; forceInternalIndex: Integer=-1): DWORD; +function g_Triggers_Create(Trigger: TTrigger; trec: TDynRecord; forceInternalIndex: Integer=-1): DWORD; var find_id: DWORD; fn, mapw: AnsiString; f, olen: Integer; begin + if (tgscope = nil) then tgscope := TTrigScope.Create(); + // Íå ñîçäàâàòü âûõîä, åñëè èãðà áåç âûõîäà if (Trigger.TriggerType = TRIGGER_EXIT) and (not LongBool(gGameSettings.Options and GAME_OPTION_ALLOWEXIT)) then @@ -2185,12 +2326,50 @@ begin if (forceInternalIndex >= olen) then begin SetLength(gTriggers, forceInternalIndex+1); - for f := olen to High(gTriggers) do gTriggers[f].TriggerType := TRIGGER_NONE; + for f := olen to High(gTriggers) do + begin + gTriggers[f].TriggerType := TRIGGER_NONE; + gTriggers[f].trigDataRec := nil; + gTriggers[f].exoInit := nil; + gTriggers[f].exoThink := nil; + gTriggers[f].exoCheck := nil; + gTriggers[f].exoAction := nil; + gTriggers[f].userVars := nil; + end; end; + f := forceInternalIndex; + gTriggers[f].trigDataRec.Free(); + gTriggers[f].exoInit.Free(); + gTriggers[f].exoThink.Free(); + gTriggers[f].exoCheck.Free(); + gTriggers[f].exoAction.Free(); + gTriggers[f].userVars.Free(); + gTriggers[f].trigDataRec := nil; + gTriggers[f].exoInit := nil; + gTriggers[f].exoThink := nil; + gTriggers[f].exoCheck := nil; + gTriggers[f].exoAction := nil; + gTriggers[f].userVars := nil; find_id := DWORD(forceInternalIndex); end; gTriggers[find_id] := Trigger; + Trigger.mapId := trec.id; + // clone trigger data + if (trec.trigRec = nil) then + begin + gTriggers[find_id].trigDataRec := nil; + //HACK! + if (gTriggers[find_id].TriggerType <> TRIGGER_SECRET) then + begin + e_LogWritefln('trigger of type %s has no triggerdata; wtf?!', [gTriggers[find_id].TriggerType], MSG_WARNING); + end; + end + else + begin + gTriggers[find_id].trigDataRec := trec.trigRec.clone(nil); + end; + with gTriggers[find_id] do begin ID := find_id; @@ -2221,6 +2400,47 @@ begin // update cached trigger variables trigUpdateCacheData(gTriggers[find_id], gTriggers[find_id].trigDataRec); + gTriggers[find_id].userVars := nil; //THashStrVariant.Create(hsihash, hsiequ); + + try + gTriggers[find_id].exoThink := TExprBase.parseStatList(VarToStr(trec.user['exoma_think'])); + except + conwritefln('*** ERROR parsing exoma_think: [%s]', [VarToStr(trec.user['exoma_think'])]); + gTriggers[find_id].exoThink := nil; + end; + try + gTriggers[find_id].exoCheck := TExprBase.parse(VarToStr(trec.user['exoma_check'])); + except + conwritefln('*** ERROR parsing exoma_check: [%s]', [VarToStr(trec.user['exoma_check'])]); + gTriggers[find_id].exoCheck := nil; + end; + try + gTriggers[find_id].exoAction := TExprBase.parseStatList(VarToStr(trec.user['exoma_action'])); + except + conwritefln('*** ERROR parsing exoma_action: [%s]', [VarToStr(trec.user['exoma_action'])]); + gTriggers[find_id].exoAction := nil; + end; + try + gTriggers[find_id].exoInit := TExprBase.parseStatList(VarToStr(trec.user['exoma_init'])); + except + conwritefln('*** ERROR parsing exoma_init: [%s]', [VarToStr(trec.user['exoma_init'])]); + gTriggers[find_id].exoInit := nil; + end; + + if (forceInternalIndex < 0) and (gTriggers[find_id].exoInit <> nil) then + begin + //conwritefln('executing trigger init: [%s]', [gTriggers[find_id].exoInit.toString()]); + try + tgscope.me := @gTriggers[find_id]; + gTriggers[find_id].exoInit.value(tgscope); + tgscope.me := nil; + except + tgscope.me := nil; + conwritefln('*** trigger exoactivate error: %s', [gTriggers[find_id].exoInit.toString()]); + exit; + end; + end; + // Çàãðóæàåì çâóê, åñëè ýòî òðèããåð "Çâóê" if (Trigger.TriggerType = TRIGGER_SOUND) and (Trigger.tgcSoundName <> '') then begin @@ -2809,6 +3029,11 @@ begin SetLength(gTriggers[a].Activators, 0); end; gTriggers[a].trigDataRec.Free(); + + gTriggers[a].exoThink.Free(); + gTriggers[a].exoCheck.Free(); + gTriggers[a].exoAction.Free(); + gTriggers[a].userVars.Free(); end; gTriggers := nil; @@ -2823,6 +3048,10 @@ var dw: DWORD; sg: Single; b: Boolean; + kv: THashStrVariant.PEntry; + //it: THashStrVariant.TKeyValEnumerator; + //uname: AnsiString; + t: LongInt; begin // Ñ÷èòàåì êîëè÷åñòâî ñóùåñòâóþùèõ òðèããåðîâ count := Length(gTriggers); @@ -2906,6 +3135,35 @@ begin sg := gTriggers[i].Sound.GetPan(); Mem.WriteSingle(sg); end; + // uservars + if (gTriggers[i].userVars = nil) then + begin + Mem.WriteInt(0); + end + else + begin + Mem.WriteInt(gTriggers[i].userVars.count); + for kv in gTriggers[i].userVars.byKeyValue do + begin + //writeln('<', kv.key, '>:<', VarToStr(kv.value), '>'); + Mem.WriteString(kv.key); + t := LongInt(varType(kv.value)); + Mem.WriteInt(t); + case t of + varString: Mem.WriteString(AnsiString(kv.value)); + varBoolean: Mem.WriteBoolean(Boolean(kv.value)); + varShortInt: Mem.WriteInt(Integer(kv.value)); + varSmallint: Mem.WriteInt(Integer(kv.value)); + varInteger: Mem.WriteInt(Integer(kv.value)); + //varInt64: Mem.WriteInt(Integer(kv.value)); + varByte: Mem.WriteInt(Integer(kv.value)); + varWord: Mem.WriteInt(Integer(kv.value)); + varLongWord: Mem.WriteInt(Integer(kv.value)); + //varQWord: + else raise Exception.CreateFmt('cannot save uservar ''%s''', [kv.key]); + end; + end; + end; end; end; @@ -2918,6 +3176,13 @@ var b: Boolean; Trig: TTrigger; mapIndex: Integer; + uvcount: Integer; + vt: LongInt; + vv: Variant; + uvname: AnsiString; + ustr: AnsiString; + uint: LongInt; + ubool: Boolean; begin if (Mem = nil) then exit; @@ -2938,18 +3203,6 @@ begin if (Trig.TriggerType = TRIGGER_NONE) then continue; // empty one Mem.ReadInt(mapIndex); i := g_Triggers_CreateWithMapIndex(Trig, a, mapIndex); - { - if (gTriggers[i].trigData <> nil) then - begin - tw := TStrTextWriter.Create(); - try - gTriggers[i].trigData.writeTo(tw); - e_LogWritefln('=== trigger #%s loaded ==='#10'%s'#10'---', [mapIndex, tw.str]); - finally - tw.Free(); - end; - end; - } // Êîîðäèíàòû ëåâîãî âåðõíåãî óãëà: Mem.ReadInt(gTriggers[i].X); Mem.ReadInt(gTriggers[i].Y); @@ -3019,7 +3272,36 @@ begin gTriggers[i].Sound.SetPosition(dw); end end; + // uservars + gTriggers[i].userVars.Free(); + gTriggers[i].userVars := nil; + Mem.ReadInt(uvcount); + if (uvcount > 0) then + begin + gTriggers[i].userVars := THashStrVariant.Create(hsihash, hsiequ); + vv := Unassigned; + while (uvcount > 0) do + begin + Dec(uvcount); + uvname := ''; + Mem.ReadString(uvname); + Mem.ReadInt(vt); + case vt of + varString: begin ustr := ''; Mem.ReadString(ustr); vv := ustr; end; + varBoolean: begin Mem.ReadBoolean(ubool); vv := ubool; end; + varShortInt: begin Mem.ReadInt(uint); vv := ShortInt(uint); end; + varSmallint: begin Mem.ReadInt(uint); vv := SmallInt(uint); end; + varInteger: begin Mem.ReadInt(uint); vv := LongInt(uint); end; + varByte: begin Mem.ReadInt(uint); vv := Byte(uint); end; + varWord: begin Mem.ReadInt(uint); vv := Word(uint); end; + varLongWord: begin Mem.ReadInt(uint); vv := LongWord(uint); end; + else raise Exception.CreateFmt('cannot load uservar ''%s''', [uvname]); + end; + gTriggers[i].userVars.put(uvname, vv); + end; + end; end; end; + end. diff --git a/src/mapdef/mapdef.txt b/src/mapdef/mapdef.txt index 889feee..afa8722 100644 --- a/src/mapdef/mapdef.txt +++ b/src/mapdef/mapdef.txt @@ -82,6 +82,11 @@ "keys" type ubyte offset 19 bitset Key default KEY_NONE; //WARNING: "trigdata" MUST be defined before "type", and "type" MUST be named "type" (for now, can be changed later) "triggerdata" type trigdata[128] offset 20; // the only special nested structure + //DO NOT USE! experimental feature! will be removed! + "exoma_init" type string default "" tip "will be called on trigger creation"; + "exoma_think" type string default "" tip "will be called on each think step"; + "exoma_check" type string default "" tip "will be called before activation"; + "exoma_action" type string default "" tip "will be called on activation"; } diff --git a/src/shared/BinEditor.pas b/src/shared/BinEditor.pas index 25526e1..e1e9022 100644 --- a/src/shared/BinEditor.pas +++ b/src/shared/BinEditor.pas @@ -30,25 +30,26 @@ Type FData: Pointer; FPosition: Cardinal; - Procedure WriteVar(Var x; varSize: Cardinal); + Procedure WriteVar (var x; varSize: Cardinal); Procedure ExtendMemory(addLen: Cardinal); Public - Constructor Create(aSize: Cardinal); - Destructor Destroy(); Override; - Procedure WriteByte(Var x: Byte); - Procedure WriteWord(Var x: Word); - Procedure WriteDWORD(Var x: DWORD); - Procedure WriteShortInt(Var x: ShortInt); - Procedure WriteSmallInt(Var x: SmallInt); - Procedure WriteInt(Var x: Integer); - Procedure WriteSingle(Var x: Single); - Procedure WriteBoolean(Var x: Boolean); - Procedure WriteString(const x: AnsiString; aMaxLen: Word=65535); - Procedure WriteMemory(Var x: Pointer; memSize: Cardinal); - Procedure Fill(aLen: Cardinal; aFillSym: Byte); - Procedure SaveToFile(Var aFile: File); - Procedure SaveToMemory(Var aMem: TBinMemoryWriter); + Constructor Create (aSize: Cardinal); + Destructor Destroy (); Override; + + Procedure WriteByte (x: Byte); + Procedure WriteWord (x: Word); + Procedure WriteDWORD (x: DWORD); + Procedure WriteShortInt (x: ShortInt); + Procedure WriteSmallInt (x: SmallInt); + Procedure WriteInt (x: Integer); + Procedure WriteSingle (x: Single); + Procedure WriteBoolean (x: Boolean); + Procedure WriteString (const x: AnsiString; aMaxLen: Word=65535); + Procedure WriteMemory (x: Pointer; memSize: Cardinal); + Procedure Fill (aLen: Cardinal; aFillSym: Byte); + Procedure SaveToFile (Var aFile: File); + Procedure SaveToMemory (Var aMem: TBinMemoryWriter); End; TBinMemoryReader = Class (TObject) @@ -161,14 +162,11 @@ begin Inherited; end; -Procedure TBinMemoryWriter.WriteVar(Var x; varSize: Cardinal); +Procedure TBinMemoryWriter.WriteVar (var x; varSize: Cardinal); begin - if (FPosition + varSize) > FSize then - ExtendMemory(varSize); - - CopyMemory(Pointer(NativeUInt(FData) + FPosition), - @x, varSize); - FPosition := FPosition + varSize; + if (FPosition+varSize > FSize) then ExtendMemory(varSize); + CopyMemory(Pointer(PtrUInt(FData)+FPosition), @x, varSize); + FPosition := FPosition+varSize; end; Procedure TBinMemoryWriter.ExtendMemory(addLen: Cardinal); @@ -197,51 +195,46 @@ begin e_WriteLog('Save Memory Extended: '+IntToStr(FSize), MSG_NOTIFY); end; -Procedure TBinMemoryWriter.WriteByte(Var x: Byte); +Procedure TBinMemoryWriter.WriteByte (x: Byte); begin WriteVar(x, SizeOf(Byte)); end; -Procedure TBinMemoryWriter.WriteWord(Var x: Word); +Procedure TBinMemoryWriter.WriteWord (x: Word); begin WriteVar(x, SizeOf(Word)); end; -Procedure TBinMemoryWriter.WriteDWORD(Var x: DWORD); +Procedure TBinMemoryWriter.WriteDWORD (x: DWORD); begin WriteVar(x, SizeOf(DWORD)); end; -Procedure TBinMemoryWriter.WriteShortInt(Var x: ShortInt); +Procedure TBinMemoryWriter.WriteShortInt (x: ShortInt); begin WriteVar(x, SizeOf(ShortInt)); end; -Procedure TBinMemoryWriter.WriteSmallInt(Var x: SmallInt); +Procedure TBinMemoryWriter.WriteSmallInt (x: SmallInt); begin WriteVar(x, SizeOf(SmallInt)); end; -Procedure TBinMemoryWriter.WriteInt(Var x: Integer); +Procedure TBinMemoryWriter.WriteInt (x: Integer); begin WriteVar(x, SizeOf(Integer)); end; -Procedure TBinMemoryWriter.WriteSingle(Var x: Single); +Procedure TBinMemoryWriter.WriteSingle (x: Single); begin WriteVar(x, SizeOf(Single)); end; -Procedure TBinMemoryWriter.WriteBoolean(Var x: Boolean); +Procedure TBinMemoryWriter.WriteBoolean (x: Boolean); var y: Byte; - begin - if x then - y := 1 - else - y := 0; - + if x then y := 1 else y := 0; WriteVar(y, SizeOf(Byte)); end; @@ -264,34 +257,27 @@ begin end; end; -Procedure TBinMemoryWriter.WriteMemory(Var x: Pointer; memSize: Cardinal); +Procedure TBinMemoryWriter.WriteMemory (x: Pointer; memSize: Cardinal); begin - if (FPosition + SizeOf(Cardinal) + memSize) > FSize then - ExtendMemory(SizeOf(Cardinal) + memSize); - -// Äëèíà áëîêà ïàìÿòè: - CopyMemory(Pointer(NativeUInt(FData) + FPosition), - @memSize, SizeOf(Cardinal)); - FPosition := FPosition + SizeOf(Cardinal); -// Áëîê ïàìÿòè: - if memSize > 0 then + if (FPosition+SizeOf(Cardinal)+memSize) > FSize then ExtendMemory(SizeOf(Cardinal)+memSize); + // Äëèíà áëîêà ïàìÿòè + CopyMemory(Pointer(PtrUInt(FData)+FPosition), @memSize, SizeOf(Cardinal)); + FPosition := FPosition+SizeOf(Cardinal); + // Áëîê ïàìÿòè + if (memSize > 0) then begin - CopyMemory(Pointer(NativeUInt(FData) + FPosition), - x, memSize); - FPosition := FPosition + memSize; + CopyMemory(Pointer(PtrUInt(FData)+FPosition), x, memSize); + FPosition := FPosition+memSize; end; end; -Procedure TBinMemoryWriter.Fill(aLen: Cardinal; aFillSym: Byte); +Procedure TBinMemoryWriter.Fill (aLen: Cardinal; aFillSym: Byte); begin - if (FPosition + aLen) > FSize then - ExtendMemory(aLen); - - if aLen > 0 then + if (FPosition+aLen > FSize) then ExtendMemory(aLen); + if (aLen > 0) then begin - FillMemory(Pointer(NativeUInt(FData) + FPosition), - aLen, aFillSym); - FPosition := FPosition + aLen; + FillMemory(Pointer(PtrUInt(FData) + FPosition), aLen, aFillSym); + FPosition := FPosition+aLen; end; end; diff --git a/src/shared/exoma.pas b/src/shared/exoma.pas new file mode 100644 index 0000000..9d628e5 --- /dev/null +++ b/src/shared/exoma.pas @@ -0,0 +1,1007 @@ +(* Copyright (C) DooM 2D:Forever Developers + * + * 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 . + *) +{$INCLUDE a_modes.inc} +unit exoma; + +interface + +uses + typinfo, Variants, hashtable, xparser; + + +// ////////////////////////////////////////////////////////////////////////// // +type + TPropHash = class + private + mClass: TClass; + mNames: THashStrInt; + pl: PPropList; + pc: Integer; + + public + constructor Create (aklass: TClass); + destructor Destroy (); override; + + function get (obj: TObject; const fldname: AnsiString; out v: Variant): Boolean; + function put (obj: TObject; const fldname: AnsiString; var v: Variant): Boolean; + end; + + +// ////////////////////////////////////////////////////////////////////////// // +type + TExprScope = class + public + function getObj (const aname: AnsiString): TObject; virtual; + function getField (obj: TObject; const afldname: AnsiString): Variant; virtual; + procedure setField (obj: TObject; const afldname: AnsiString; var aval: Variant); virtual; + end; + + TExprBase = class + public + class function coerce2bool (var v0: Variant): Boolean; + class function toInt (var v: Variant): LongInt; + public + class procedure error (); + class function parse (pr: TTextParser; allowAssign: Boolean=false): TExprBase; + class function parse (const str: AnsiString; allowAssign: Boolean=false): TExprBase; + class function parseStatList (const str: AnsiString): TExprBase; + public + function value (scope: TExprScope): Variant; virtual; abstract; + procedure assign (scope: TExprScope; var v: Variant); virtual; + function clone (): TExprBase; virtual; abstract; + end; + + TExprStatList = class(TExprBase) + private + mList: array of TExprBase; + public + constructor Create (); + destructor Destroy (); override; + function value (scope: TExprScope): Variant; override; + function toString (): AnsiString; override; + function clone (): TExprBase; override; + end; + + TObjExpr = class(TExprBase) + private + mName: AnsiString; + public + constructor Create (const aval: AnsiString); + + function value (scope: TExprScope): Variant; override; + function toString (): AnsiString; override; + function clone (): TExprBase; override; + end; + + TLitExpr = class(TExprBase) + private + mValue: Variant; + public + constructor Create (aval: Boolean); + constructor Create (aval: LongInt); + constructor Create (const aval: AnsiString); + + function value (scope: TExprScope): Variant; override; + function toString (): AnsiString; override; + function clone (): TExprBase; override; + end; + + TUnExpr = class(TExprBase) + private + mOp0: TExprBase; + public + constructor Create (aop0: TExprBase); + destructor Destroy (); override; + function clone (): TExprBase; override; + end; + + TUnExprNeg = class(TUnExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TUnExprNot = class(TUnExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + + TDotExpr = class(TExprBase) + private + mOp0: TExprBase; + mField: AnsiString; + public + constructor Create (aop0: TExprBase; const afield: AnsiString); + function value (scope: TExprScope): Variant; override; + procedure assign (scope: TExprScope; var v: Variant); override; + function toString (): AnsiString; override; + function clone (): TExprBase; override; + end; + + TBinExpr = class(TExprBase) + private + mOp0, mOp1: TExprBase; + private + class procedure coerce (var v0, v1: Variant); // modifies both variants + public + constructor Create (aop0, aop1: TExprBase); + destructor Destroy (); override; + function clone (): TExprBase; override; + end; + + TBinExprAdd = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprSub = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprMul = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprDiv = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprMod = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + + TBinExprLogAnd = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprLogOr = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + + TBinExprCmpLess = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprCmpGreat = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprCmpLessEqu = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprCmpGreatEqu = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprCmpEqu = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + TBinExprCmpNotEqu = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + + TBinAssign = class(TBinExpr) public function value (scope: TExprScope): Variant; override; function toString (): AnsiString; override; end; + + +// ////////////////////////////////////////////////////////////////////////// // +function typeKind2Str (t: TTypeKind): AnsiString; + + +implementation + +uses + SysUtils, utils; + + +// ////////////////////////////////////////////////////////////////////////// // +function typeKind2Str (t: TTypeKind): AnsiString; +begin + case t of + tkUnknown: result := 'Unknown'; + tkInteger: result := 'Integer'; + tkChar: result := 'AnsiChar'; + tkEnumeration: result := 'Enumeration'; + tkFloat: result := 'Float'; + tkSet: result := 'Set'; + tkMethod: result := 'Method'; + tkSString: result := 'ShortString'; + tkLString: result := 'LString'; + tkAString: result := 'AnsiString'; + tkWString: result := 'WideString'; + tkVariant: result := 'Variant'; + tkArray: result := 'Array'; + tkRecord: result := 'Record'; + tkInterface: result := 'Interface'; + tkClass: result := 'Class'; + tkObject: result := 'Object'; + tkWChar: result := 'WideChar'; + tkBool: result := 'Boolean'; + tkInt64: result := 'Int64'; + tkQWord: result := 'UInt64'; + tkDynArray: result := 'DynArray'; + tkInterfaceRaw: result := 'InterfaceRaw'; + tkProcVar: result := 'ProcVar'; + tkUString: result := 'UString'; + tkUChar: result := 'UChar'; + tkHelper: result := 'Helper'; + tkFile: result := 'File'; + tkClassRef: result := 'ClassRef'; + tkPointer: result := 'Pointer'; + else result := ''; + end; +end; + + +// ////////////////////////////////////////////////////////////////////////// // +(* +procedure dumpPublishedProperties (obj: TObject); +var + pt: PTypeData; + pi: PTypeInfo; + i, j: Integer; + pp: PPropList; +begin + if (obj = nil) then exit; + //e_LogWritefln('Object of type ''%s'':', [obj.ClassName]); + pi := obj.ClassInfo; + pt := GetTypeData(pi); + //e_LogWritefln('property count: %s', [pt.PropCount]); + GetMem(pp, pt^.PropCount*sizeof(Pointer)); + try + j := GetPropList(pi, [tkInteger, tkBool, tkSString, tkLString, tkAString, tkSet, tkEnumeration], pp); + //e_LogWritefln('ordinal property count: %s', [j]); + for i := 0 to j-1 do + begin + { + if (typinfo.PropType(obj, pp^[i].name) in [tkSString, tkLString, tkAString]) then + begin + e_LogWritefln(' #%s: <%s>; type: %s; value: <%s>', [i+1, pp^[i].name, typeKind2Str(typinfo.PropType(obj, pp^[i].name)), GetStrProp(obj, pp^[i])]); + end + else if (typinfo.PropType(obj, pp^[i].name) = tkSet) then + begin + e_LogWritefln(' #%s: <%s>; type: %s; value: %s', [i+1, pp^[i].name, typeKind2Str(typinfo.PropType(obj, pp^[i].name)), GetSetProp(obj, pp^[i], true)]); + end + else if (typinfo.PropType(obj, pp^[i].name) = tkEnumeration) then + begin + e_LogWritefln(' #%s: <%s>; type: %s; value: <%s>', [i+1, pp^[i].name, typeKind2Str(typinfo.PropType(obj, pp^[i].name)), GetEnumProp(obj, pp^[i])]); + end + else + begin + e_LogWritefln(' #%s: <%s>; type: %s; value: %s', [i+1, pp^[i].name, typeKind2Str(typinfo.PropType(obj, pp^[i].name)), GetOrdProp(obj, pp^[i])]); + end; + } + end; + finally + FreeMem(pp); + end; +end; +*) + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TPropHash.Create (aklass: TClass); +var + pi: PTypeInfo; + pt: PTypeData; + idx: Integer; +begin + mClass := aklass; + mNames := hashNewStrInt(); + pi := aklass.ClassInfo; + pt := GetTypeData(pi); + GetMem(pl, pt^.PropCount*sizeof(Pointer)); + pc := GetPropList(pi, [tkInteger, tkBool, tkSString, tkLString, tkAString, {tkSet,} tkEnumeration], pl); + for idx := 0 to pc-1 do mNames.put(pl^[idx].name, idx); +end; + +destructor TPropHash.Destroy (); +begin + mNames.Free(); + mNames := nil; + if (pl <> nil) then FreeMem(pl); + pl := nil; + pc := 0; + mClass := nil; +end; + +function TPropHash.get (obj: TObject; const fldname: AnsiString; out v: Variant): Boolean; +var + idx: Integer; +begin + result := false; + if mNames.get(fldname, idx) then + begin + result := true; + case pl^[idx].PropType.Kind of + tkSString, tkLString, tkAString: v := GetStrProp(obj, pl^[idx]); + tkEnumeration: v := GetEnumProp(obj, pl^[idx]); + tkBool: if (GetOrdProp(obj, pl^[idx]) = 0) then v := false else v := true; + tkInteger, tkChar: v := LongInt(GetOrdProp(obj, pl^[idx])); + //tkFloat: result := 'Float'; + //tkClass: result := 'Class'; + //tkInt64: result := 'Int64'; + //tkClassRef: result := 'ClassRef'; + else result := false; + end; + if result then exit; + end; + v := Unassigned; +end; + +function TPropHash.put (obj: TObject; const fldname: AnsiString; var v: Variant): Boolean; +var + idx: Integer; +begin + result := false; + if mNames.get(fldname, idx) then + begin + result := true; + case pl^[idx].PropType.Kind of + tkSString, tkLString, tkAString: SetStrProp(obj, pl^[idx], VarToStr(v)); + tkEnumeration: SetEnumProp(obj, pl^[idx], VarToStr(v)); + tkBool: if TExprBase.coerce2bool(v) then SetOrdProp(obj, pl^[idx], 1) else SetOrdProp(obj, pl^[idx], 0); + tkInteger, tkChar: SetOrdProp(obj, pl^[idx], TExprBase.toInt(v)); + //tkFloat: result := 'Float'; + //tkClass: result := 'Class'; + //tkInt64: result := 'Int64'; + //tkClassRef: result := 'ClassRef'; + else result := false; + end; + if result then exit; + end; +end; + + +// ////////////////////////////////////////////////////////////////////////// // +function TExprScope.getObj (const aname: AnsiString): TObject; begin result := nil; TExprBase.error(); end; +function TExprScope.getField (obj: TObject; const afldname: AnsiString): Variant; begin result := Unassigned; TExprBase.error(); end; +procedure TExprScope.setField (obj: TObject; const afldname: AnsiString; var aval: Variant); begin TExprBase.error(); end; + + +// ////////////////////////////////////////////////////////////////////////// // +class procedure TExprBase.error (); begin raise Exception.Create('math error'); end; + +class function TExprBase.coerce2bool (var v0: Variant): Boolean; +begin + case varType(v0) of + varEmpty: result := false; + varNull: result := false; + varSingle: result := (Single(v0) <> 0.0); + varDouble: result := (Double(v0) <> 0.0); + varString: result := (Length(AnsiString(v0)) <> 0); + varBoolean: result := Boolean(v0); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := (LongInt(v0) <> 0); + varInt64: result := (Int64(v0) <> 0); + varQWord: result := (UInt64(v0) <> 0); + else begin result := false; error(); end; + end; +end; + +class function TExprBase.toInt (var v: Variant): LongInt; +begin + case varType(v) of + varSingle: result := trunc(Single(v)); + varDouble: result := trunc(Double(v)); + varBoolean: if Boolean(v) then result := 1 else result := 0; + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(v); + varInt64: result := LongInt(Int64(v)); + else begin result := 0; TExprBase.error(); end; + end; +end; + +procedure TExprBase.assign (scope: TExprScope; var v: Variant); begin error(); end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TExprStatList.Create (); begin mList := nil; end; +destructor TExprStatList.Destroy (); var f: Integer; begin for f := 0 to High(mList) do mList[f].Free(); mList := nil; end; + +function TExprStatList.value (scope: TExprScope): Variant; +var + f: Integer; +begin + result := false; + for f := 0 to High(mList) do result := mList[f].value(scope); +end; +function TExprStatList.toString (): AnsiString; +var + f: Integer; +begin + result := ''; + for f := 0 to High(mList) do result += mList[f].toString()+';'; +end; +function TExprStatList.clone (): TExprBase; +var + r: TExprStatList; + f: Integer; +begin + r := TExprStatList.Create(); + SetLength(r.mList, Length(mList)); + for f := 0 to High(mList) do r.mList[f] := nil; + try + for f := 0 to High(mList) do r.mList[f] := mList[f].clone(); + except + r.Free(); + end; + result := r; +end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TObjExpr.Create (const aval: AnsiString); begin mName := aval; end; +function TObjExpr.value (scope: TExprScope): Variant; begin result := UInt64(PtrUInt(Pointer(scope.getObj(mName)))); end; +function TObjExpr.toString (): AnsiString; begin result := mName; end; +function TObjExpr.clone (): TExprBase; begin result := TObjExpr.Create(mName); end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TLitExpr.Create (aval: Boolean); begin mValue := aval; end; +constructor TLitExpr.Create (aval: LongInt); begin mValue := aval; end; +constructor TLitExpr.Create (const aval: AnsiString); begin mValue := aval; end; +function TLitExpr.value (scope: TExprScope): Variant; begin result := mValue; end; +function TLitExpr.toString (): AnsiString; begin result := VarToStr(mValue); end; +function TLitExpr.clone (): TExprBase; begin result := TLitExpr.Create(0); (result as TLitExpr).mValue := mValue; end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TUnExpr.Create (aop0: TExprBase); begin mOp0 := aop0; end; +destructor TUnExpr.Destroy (); begin mOp0.Free(); inherited; end; +function TUnExpr.clone (): TExprBase; begin result := (self.ClassType.Create() as TUnExpr); (result as TUnExpr).mOp0 := mOp0.clone(); end; + +function TUnExprNeg.value (scope: TExprScope): Variant; +begin + result := mOp0.value(scope); + case varType(result) of + varSingle: result := -Single(result); + varDouble: result := -Double(result); + varShortInt, varSmallInt, varInteger, varByte, varWord: result := -LongInt(result); + varInt64: result := -Int64(result); + varLongWord: result := -LongInt(result); + else error(); + end; +end; + +function TUnExprNeg.toString (): AnsiString; begin result := '-('+mOp0.toString()+')'; end; + +function TUnExprNot.value (scope: TExprScope): Variant; +begin + result := mOp0.value(scope); + result := not coerce2bool(result); +end; + +function TUnExprNot.toString (): AnsiString; begin result := '!('+mOp0.toString()+')'; end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TDotExpr.Create (aop0: TExprBase; const afield: AnsiString); +begin + mOp0 := aop0; + mField := afield; +end; + +function TDotExpr.value (scope: TExprScope): Variant; +begin + result := mOp0.value(scope); + if (varType(result) <> varQWord) then error(); + result := scope.getField(TObject(PtrUInt(UInt64(result))), mField); +end; + +procedure TDotExpr.assign (scope: TExprScope; var v: Variant); +var + o: Variant; +begin + o := mOp0.value(scope); + if (varType(o) <> varQWord) then error(); + scope.setField(TObject(PtrUInt(UInt64(o))), mField, v); +end; + +function TDotExpr.clone (): TExprBase; begin result := TDotExpr.Create(mOp0, mField); end; + +function TDotExpr.toString (): AnsiString; begin result := mOp0.toString()+'.'+mField; end; + + +// ////////////////////////////////////////////////////////////////////////// // +constructor TBinExpr.Create (aop0, aop1: TExprBase); begin mOp0 := aop0; mOp1 := aop1; end; +destructor TBinExpr.Destroy (); begin mOp1.Free(); mOp0.Free(); inherited; end; +function TBinExpr.clone (): TExprBase; begin result := (self.ClassType.Create() as TBinExpr); (result as TBinExpr).mOp0 := mOp0.clone(); (result as TBinExpr).mOp1 := mOp1.clone(); end; + +class procedure TBinExpr.coerce (var v0, v1: Variant); + function isFloat (var v: Variant): Boolean; inline; + begin + case varType(v) of + varSingle, varDouble: result := true; + else result := false; + end; + end; + + function isInt (var v: Variant): Boolean; inline; + begin + case varType(v) of + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := true; + else result := false; + end; + end; + + function isBool (var v: Variant): Boolean; inline; + begin + result := (varType(v) = varBoolean); + end; + + function isStr (var v: Variant): Boolean; inline; + begin + result := (varType(v) = varString); + end; + +begin + if (varType(v0) <> varType(v1)) then + begin + if isStr(v0) or isStr(v1) then + begin + if isFloat(v0) then v0 := formatstrf('%s', [Double(v0)]) + else if isInt(v0) then v0 := formatstrf('%s', [LongInt(v0)]) + else if isBool(v0) then v0 := formatstrf('%s', [Boolean(v0)]) + else if isStr(v0) then begin end + else error(); + if isFloat(v1) then v1 := formatstrf('%s', [Double(v1)]) + else if isInt(v1) then v1 := formatstrf('%s', [LongInt(v1)]) + else if isBool(v1) then v1 := formatstrf('%s', [Boolean(v1)]) + else if isStr(v0) then begin end + else error(); + end + else if isFloat(v0) or isFloat(v1) then + begin + if isFloat(v0) or isInt(v0) then v0 := Double(v0) + else if isBool(v0) then begin if Boolean(v0) then v0 := Double(1.0) else v0 := Double(0.0); end + else error(); + if isFloat(v1) or isInt(v1) then v1 := Double(v1) + else if isBool(v1) then begin if Boolean(v1) then v1 := Double(1.0) else v1 := Double(0.0); end + else error(); + end + else if isInt(v0) or isInt(v1) then + begin + if isBool(v0) then begin if Boolean(v0) then v0 := LongInt(1) else v0 := LongInt(0); end + else if isFloat(v0) then v0 := LongInt(trunc(Double(v0))) + else if isInt(v0) then begin end + else error(); + if isBool(v1) then begin if Boolean(v1) then v1 := LongInt(1) else v1 := LongInt(0); end + else if isFloat(v1) then v1 := LongInt(trunc(Double(v1))) + else if isInt(v1) then begin end + else error(); + end + else + begin + error(); + end; + end; +end; + + +// ////////////////////////////////////////////////////////////////////////// // +function TBinExprAdd.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Double(result)+Double(r1); + varString: result := AnsiString(result)+AnsiString(r1); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(result)+LongInt(r1); + varInt64: result := Int64(result)+Int64(r1); + else error(); + end; +end; +function TBinExprAdd.toString (): AnsiString; begin result := '('+mOp0.toString()+'+'+mOp1.toString+')'; end; + +function TBinExprSub.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Double(result)-Double(r1); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(result)-LongInt(r1); + varInt64: result := Int64(result)-Int64(r1); + else error(); + end; +end; +function TBinExprSub.toString (): AnsiString; begin result := '('+mOp0.toString()+'-'+mOp1.toString+')'; end; + +function TBinExprMul.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Double(result)*Double(r1); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(result)*LongInt(r1); + varInt64: result := Int64(result)*Int64(r1); + else error(); + end; +end; +function TBinExprMul.toString (): AnsiString; begin result := '('+mOp0.toString()+'*'+mOp1.toString+')'; end; + +function TBinExprDiv.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Double(result)/Double(r1); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(result) div LongInt(r1); + varInt64: result := Int64(result) div Int64(r1); + else error(); + end; +end; +function TBinExprDiv.toString (): AnsiString; begin result := '('+mOp0.toString()+'/'+mOp1.toString+')'; end; + +function TBinExprMod.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := LongInt(result) mod LongInt(r1); + varInt64: result := Int64(result) mod Int64(r1); + else error(); + end; +end; +function TBinExprMod.toString (): AnsiString; begin result := '('+mOp0.toString()+'%'+mOp1.toString+')'; end; + +function TBinExprLogAnd.value (scope: TExprScope): Variant; +begin + result := mOp0.value(scope); + if not coerce2bool(result) then begin result := false; exit; end; + result := mOp1.value(scope); + result := coerce2bool(result); +end; +function TBinExprLogAnd.toString (): AnsiString; begin result := '('+mOp0.toString()+'&&'+mOp1.toString+')'; end; + +function TBinExprLogOr.value (scope: TExprScope): Variant; +begin + result := mOp0.value(scope); + if coerce2bool(result) then begin result := true; exit; end; + result := mOp1.value(scope); + result := coerce2bool(result); +end; +function TBinExprLogOr.toString (): AnsiString; begin result := '('+mOp0.toString()+'||'+mOp1.toString+')'; end; + +function TBinExprCmpLess.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) < Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) < LongInt(r1)); + varInt64: result := Boolean(Int64(result) < Int64(r1)); + varString: result := Boolean(AnsiString(result) < AnsiString(r1)); + else error(); + end; +end; +function TBinExprCmpLess.toString (): AnsiString; begin result := '('+mOp0.toString()+'<'+mOp1.toString+')'; end; + +function TBinExprCmpGreat.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) > Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) > LongInt(r1)); + varInt64: result := Boolean(Int64(result) > Int64(r1)); + varString: result := Boolean(AnsiString(result) > AnsiString(r1)); + else error(); + end; +end; +function TBinExprCmpGreat.toString (): AnsiString; begin result := '('+mOp0.toString()+'>'+mOp1.toString+')'; end; + +function TBinExprCmpLessEqu.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) <= Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) <= LongInt(r1)); + varInt64: result := Boolean(Int64(result) <= Int64(r1)); + varString: result := Boolean(AnsiString(result) <= AnsiString(r1)); + else error(); + end; +end; +function TBinExprCmpLessEqu.toString (): AnsiString; begin result := '('+mOp0.toString()+'<='+mOp1.toString+')'; end; + +function TBinExprCmpGreatEqu.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) >= Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) >= LongInt(r1)); + varInt64: result := Boolean(Int64(result) >= Int64(r1)); + varString: result := Boolean(AnsiString(result) >= AnsiString(r1)); + else error(); + end; +end; +function TBinExprCmpGreatEqu.toString (): AnsiString; begin result := '('+mOp0.toString()+'>='+mOp1.toString+')'; end; + +function TBinExprCmpEqu.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) = Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) = LongInt(r1)); + varInt64: result := Boolean(Int64(result) = Int64(r1)); + varString: result := Boolean(AnsiString(result) = AnsiString(r1)); + varBoolean: result := (Boolean(result) = Boolean(r1)); + varQWord: result := (UInt64(result) = UInt64(r1)); + else error(); + end; +end; +function TBinExprCmpEqu.toString (): AnsiString; begin result := '('+mOp0.toString()+'=='+mOp1.toString+')'; end; + +function TBinExprCmpNotEqu.value (scope: TExprScope): Variant; +var + r1: Variant; +begin + result := mOp0.value(scope); + r1 := mOp1.value(scope); + coerce(result, r1); + case varType(result) of + varSingle, varDouble: result := Boolean(Double(result) <> Double(r1)); + varShortInt, varSmallint, varInteger, varByte, varWord, varLongWord: result := Boolean(LongInt(result) <> LongInt(r1)); + varInt64: result := Boolean(Int64(result) <> Int64(r1)); + varString: result := Boolean(AnsiString(result) <> AnsiString(r1)); + varBoolean: result := (Boolean(result) <> Boolean(r1)); + varQWord: result := (UInt64(result) <> UInt64(r1)); + else error(); + end; +end; +function TBinExprCmpNotEqu.toString (): AnsiString; begin result := '('+mOp0.toString()+'<>'+mOp1.toString+')'; end; + + +// ////////////////////////////////////////////////////////////////////////// // +function TBinAssign.value (scope: TExprScope): Variant; +begin + result := mOp1.value(scope); + mOp0.assign(scope, result); +end; + +function TBinAssign.toString (): AnsiString; begin result := mOp0.toString()+'='+mOp1.toString(); end; + + +// ////////////////////////////////////////////////////////////////////////// // +class function TExprBase.parse (const str: AnsiString; allowAssign: Boolean=false): TExprBase; +var + pr: TTextParser; +begin + pr := TStrTextParser.Create(str); + try + result := parse(pr, allowAssign); + if (pr.tokType <> pr.TTEOF) then begin result.Free(); error(); end; + finally + pr.Free(); + end; +end; + +class function TExprBase.parseStatList (const str: AnsiString): TExprBase; +var + pr: TTextParser; + r: TExprStatList; + e: TExprBase; +begin + pr := TStrTextParser.Create(str); + if (pr.tokType = pr.TTEOF) then begin pr.Free(); result := nil; exit; end; + r := TExprStatList.Create(); + result := nil; + try + while true do + begin + while pr.eatTT(pr.TTSemi) do begin end; + if (pr.tokType = pr.TTEOF) then break; + e := parse(pr, true); + if (e = nil) then break; + SetLength(r.mList, Length(r.mList)+1); + r.mList[High(r.mList)] := e; + if (pr.tokType = pr.TTEOF) then break; + pr.expectTT(pr.TTSemi); + end; + result := r; + r := nil; + finally + r.Free(); + pr.Free(); + end; +end; + + +class function TExprBase.parse (pr: TTextParser; allowAssign: Boolean=false): TExprBase; + + function expr (): TExprBase; forward; + + function doTerm (): TExprBase; + begin + result := nil; + try + if pr.eatDelim('(') then begin result := expr(); pr.expectDelim(')'); exit; end; + if pr.eatDelim('!') then begin result := expr(); result := TUnExprNot.Create(result); exit; end; + if pr.eatDelim('-') then begin result := expr(); result := TUnExprNeg.Create(result); exit; end; + if pr.eatDelim('+') then begin result := expr(); exit; end; + if (pr.tokType = pr.TTInt) then begin result := TLitExpr.Create(pr.expectInt()); exit; end; + if (pr.tokType = pr.TTStr) then begin result := TLitExpr.Create(pr.expectStr(true)); exit; end; + if (pr.tokType = pr.TTId) then + begin + if (pr.tokStr = 'true') then begin result := TLitExpr.Create(true); pr.skipToken(); exit; end; + if (pr.tokStr = 'false') then begin result := TLitExpr.Create(false); pr.skipToken(); exit; end; + if (CompareText(pr.tokStr, 'true') = 0) or (CompareText(pr.tokStr, 'false') = 0) then error(); + result := TObjExpr.Create(pr.expectId()); + while (pr.tokType = pr.TTDelim) and (pr.tokChar = '.') do + begin + pr.skipToken(); + result := TDotExpr.Create(result, pr.expectId()); + end; + exit; + end; + except + result.Free(); + raise; + end; + error(); + end; + + function doMulDiv (): TExprBase; + begin + result := doTerm(); + try + while true do + begin + if pr.eatDelim('*') then result := TBinExprMul.Create(result, doTerm()) + else if pr.eatDelim('/') then result := TBinExprDiv.Create(result, doTerm()) + else if pr.eatDelim('%') then result := TBinExprMod.Create(result, doTerm()) + else break; + end; + except + result.Free(); + raise; + end; + end; + + function doPlusMinus (): TExprBase; + begin + result := doMulDiv(); + try + while true do + begin + if pr.eatDelim('+') then result := TBinExprAdd.Create(result, doMulDiv()) + else if pr.eatDelim('-') then result := TBinExprSub.Create(result, doMulDiv()) + else break; + end; + except + result.Free(); + raise; + end; + end; + + function doCmp (): TExprBase; + begin + result := doPlusMinus(); + try + while true do + begin + if pr.eatDelim('<') then result := TBinExprCmpLess.Create(result, doPlusMinus()) + else if pr.eatDelim('>') then result := TBinExprCmpGreat.Create(result, doPlusMinus()) + else if pr.eatTT(pr.TTLessEqu) then result := TBinExprCmpLessEqu.Create(result, doPlusMinus()) + else if pr.eatTT(pr.TTGreatEqu) then result := TBinExprCmpGreatEqu.Create(result, doPlusMinus()) + else break; + end; + except + result.Free(); + raise; + end; + end; + + function doCmpEqu (): TExprBase; + begin + result := doCmp(); + try + while true do + begin + if pr.eatTT(pr.TTEqu) then result := TBinExprCmpEqu.Create(result, doCmp()) + else if pr.eatTT(pr.TTNotEqu) then result := TBinExprCmpNotEqu.Create(result, doCmp()) + else break; + end; + except + result.Free(); + raise; + end; + end; + + function doLogAnd (): TExprBase; + begin + result := doCmpEqu(); + try + while true do + begin + if pr.eatTT(pr.TTLogAnd) then result := TBinExprLogAnd.Create(result, doCmpEqu()) else break; + end; + except + result.Free(); + raise; + end; + end; + + function doLogOr (): TExprBase; + begin + result := doLogAnd(); + try + while true do + begin + if pr.eatTT(pr.TTLogOr) then result := TBinExprLogOr.Create(result, doLogAnd()) else break; + end; + except + result.Free(); + raise; + end; + end; + + // funcall, [], dot + // !, ~ + // *, /, % + // +, - + // <<, >> + // <, <=, >, >= + // ==, != + // & + // ^ + // | + // && + // || + + function expr (): TExprBase; + var + neg: Boolean = false; + begin + if pr.eatDelim('-') then neg := true + else if pr.eatDelim('+') then neg := false; + result := doLogOr(); + if neg then result := TUnExprNeg.Create(result); + end; + +var + oas: Boolean; +begin + if (pr = nil) or (pr.tokType = pr.TTEOF) then begin result := nil; exit; end; + oas := pr.allowSignedNumbers; + pr.allowSignedNumbers := false; + try + result := expr(); + if allowAssign and pr.eatDelim('=') then + try + result := TBinAssign.Create(result, expr()); + except + result.Free(); + end; + finally + pr.allowSignedNumbers := oas; + end; +end; + + +{ + varEmpty: + varNull: + varSingle: + varDouble: + varDecimal: + varCurrency: + varDate: + varOleStr: + varStrArg: + varString: + varDispatch: + varBoolean: + varVariant: + varUnknown: + varShortInt: + varSmallint: + varInteger: + varInt64: + varByte: + varWord: + varLongWord: + varQWord: + varError: +} +end. diff --git a/src/shared/hashtable.pas b/src/shared/hashtable.pas index 8aaa522..fa6ec85 100644 --- a/src/shared/hashtable.pas +++ b/src/shared/hashtable.pas @@ -54,6 +54,8 @@ type type TEntryArray = array of TEntry; + public + type TValEnumerator = record private mEntries: TEntryArray; @@ -62,6 +64,7 @@ type constructor Create (const aents: TEntryArray; afirst, alast: Integer); function MoveNext (): Boolean; inline; function getCurrent (): ValueT; inline; + function GetEnumerator (): TValEnumerator; inline; property Current: ValueT read getCurrent; end; @@ -73,6 +76,7 @@ type constructor Create (const aents: TEntryArray; afirst, alast: Integer); function MoveNext (): Boolean; inline; function getCurrent (): KeyT; inline; + function GetEnumerator (): TKeyEnumerator; inline; property Current: KeyT read getCurrent; end; @@ -84,6 +88,7 @@ type constructor Create (const aents: TEntryArray; afirst, alast: Integer); function MoveNext (): Boolean; inline; function getCurrent (): PEntry; inline; + function GetEnumerator (): TKeyValEnumerator; inline; property Current: PEntry read getCurrent; end; @@ -959,6 +964,11 @@ begin end; +function THashBase.TValEnumerator.GetEnumerator (): TValEnumerator; inline; begin result.mEntries := self.mEntries; result.mFirstEntry := self.mFirstEntry; result.mLastEntry := self.mLastEntry; result.cur := self.cur; end; +function THashBase.TKeyEnumerator.GetEnumerator (): TKeyEnumerator; inline; begin result.mEntries := self.mEntries; result.mFirstEntry := self.mFirstEntry; result.mLastEntry := self.mLastEntry; result.cur := self.cur; end; +function THashBase.TKeyValEnumerator.GetEnumerator (): TKeyValEnumerator; inline; begin result.mEntries := self.mEntries; result.mFirstEntry := self.mFirstEntry; result.mLastEntry := self.mLastEntry; result.cur := self.cur; end; + + // ////////////////////////////////////////////////////////////////////////// // constructor THashBase.TValEnumerator.Create (const aents: TEntryArray; afirst, alast: Integer); begin diff --git a/src/shared/mapdef.inc b/src/shared/mapdef.inc index 2e457b6..1fe1c03 100644 --- a/src/shared/mapdef.inc +++ b/src/shared/mapdef.inc @@ -483,566 +483,584 @@ const defaultMapDef: AnsiString = ''+ #116#114#105#103#103#101#114#100#97#116#97#34#32#116#121#112#101#32#116#114+ #105#103#100#97#116#97#91#49#50#56#93#32#111#102#102#115#101#116#32#50#48#59+ #32#47#47#32#116#104#101#32#111#110#108#121#32#115#112#101#99#105#97#108#32+ - #110#101#115#116#101#100#32#115#116#114#117#99#116#117#114#101#10#125#10#10+ - #10#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ + #110#101#115#116#101#100#32#115#116#114#117#99#116#117#114#101#10#32#32#47+ + #47#68#79#32#78#79#84#32#85#83#69#33#32#101#120#112#101#114#105#109#101#110+ + #116#97#108#32#102#101#97#116#117#114#101#33#32#119#105#108#108#32#98#101#32+ + #114#101#109#111#118#101#100#33#10#32#32#34#101#120#111#109#97#95#105#110+ + #105#116#34#32#116#121#112#101#32#115#116#114#105#110#103#32#100#101#102#97+ + #117#108#116#32#34#34#32#116#105#112#32#34#119#105#108#108#32#98#101#32#99+ + #97#108#108#101#100#32#111#110#32#116#114#105#103#103#101#114#32#99#114#101+ + #97#116#105#111#110#34#59#10#32#32#34#101#120#111#109#97#95#116#104#105#110+ + #107#34#32#116#121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117+ + #108#116#32#34#34#32#116#105#112#32#34#119#105#108#108#32#98#101#32#99#97+ + #108#108#101#100#32#111#110#32#101#97#99#104#32#116#104#105#110#107#32#115+ + #116#101#112#34#59#10#32#32#34#101#120#111#109#97#95#99#104#101#99#107#34#32+ + #116#121#112#101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32+ + #34#34#32#116#105#112#32#34#119#105#108#108#32#98#101#32#99#97#108#108#101+ + #100#32#98#101#102#111#114#101#32#97#99#116#105#118#97#116#105#111#110#34#59+ + #10#32#32#34#101#120#111#109#97#95#97#99#116#105#111#110#34#32#116#121#112+ + #101#32#115#116#114#105#110#103#32#100#101#102#97#117#108#116#32#34#34#32+ + #116#105#112#32#34#119#105#108#108#32#98#101#32#99#97#108#108#101#100#32#111+ + #110#32#97#99#116#105#118#97#116#105#111#110#34#59#10#125#10#10#10#47#47#47+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ - #47#47#47#47#47#47#10#47#47#32#115#112#101#99#105#97#108#32#116#101#120#116+ - #117#114#101#32#105#100#101#110#116#105#102#105#101#114#115#44#32#117#115+ - #101#100#32#116#111#32#103#101#110#101#114#97#116#101#32#112#97#115#99#97+ - #108#32#115#111#117#114#99#101#115#10#101#110#117#109#32#84#101#120#116#117+ - #114#101#83#112#101#99#105#97#108#32#123#10#32#32#84#69#88#84#85#82#69#95#83+ - #80#69#67#73#65#76#95#87#65#84#69#82#32#61#32#45#49#44#10#32#32#84#69#88#84+ - #85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#49#32#61#32#45#50#44#10#32+ - #32#84#69#88#84#85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#50#32#61#32+ - #45#51#44#10#32#32#84#69#88#84#85#82#69#95#78#79#78#69#32#61#32#45#52#44#10+ - #125#10#10#47#47#32#100#105#114#101#99#116#105#111#110#115#10#101#110#117+ - #109#32#68#105#114#84#121#112#101#32#123#10#32#32#68#73#82#95#76#69#70#84#44+ - #32#47#47#32#48#10#32#32#68#73#82#95#82#73#71#72#84#44#32#47#47#32#49#10#32+ - #32#68#73#82#95#83#79#77#69#84#72#73#78#71#50#44#32#47#47#32#50#10#125#10#10+ - #47#47#32#116#114#105#103#103#101#114#115#10#101#110#117#109#32#84#114#105+ - #103#103#101#114#84#121#112#101#32#123#10#32#32#84#82#73#71#71#69#82#95#78+ - #79#78#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#88#73#84#44+ - #32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84#44+ - #32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#79#80#69#78#68#79#79#82#44+ - #32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79#82+ - #44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#47#47+ - #32#53#10#32#32#84#82#73#71#71#69#82#95#68#79#79#82#53#44#32#47#47#32#54#10+ - #32#32#84#82#73#71#71#69#82#95#67#76#79#83#69#84#82#65#80#44#32#47#47#32#55+ - #10#32#32#84#82#73#71#71#69#82#95#84#82#65#80#44#32#47#47#32#56#10#32#32#84+ - #82#73#71#71#69#82#95#80#82#69#83#83#44#32#47#47#32#57#10#32#32#84#82#73#71+ - #71#69#82#95#83#69#67#82#69#84#44#32#47#47#32#49#48#10#32#32#84#82#73#71#71+ - #69#82#95#76#73#70#84#85#80#44#32#47#47#32#49#49#10#32#32#84#82#73#71#71#69+ - #82#95#76#73#70#84#68#79#87#78#44#32#47#47#32#49#50#10#32#32#84#82#73#71#71+ - #69#82#95#76#73#70#84#44#32#47#47#32#49#51#10#32#32#84#82#73#71#71#69#82#95+ - #84#69#88#84#85#82#69#44#32#47#47#32#49#52#10#32#32#84#82#73#71#71#69#82#95+ - #79#78#44#32#47#47#32#49#53#10#32#32#84#82#73#71#71#69#82#95#79#70#70#44#32+ - #47#47#32#49#54#10#32#32#84#82#73#71#71#69#82#95#79#78#79#70#70#44#32#47#47+ - #32#49#55#10#32#32#84#82#73#71#71#69#82#95#83#79#85#78#68#44#32#47#47#32#49+ - #56#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#77#79#78#83#84#69#82#44+ - #32#47#47#32#49#57#10#32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84#69+ - #77#44#32#47#47#32#50#48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67#44+ - #32#47#47#32#50#49#10#32#32#84#82#73#71#71#69#82#95#80#85#83#72#44#32#47#47+ - #32#50#50#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#44#32#47#47#32#50+ - #51#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#44#32#47#47#32#50+ - #52#10#32#32#84#82#73#71#71#69#82#95#68#65#77#65#71#69#44#32#47#47#32#50#53+ - #10#32#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#44#32#47#47#32#50#54#10+ - #32#32#84#82#73#71#71#69#82#95#83#72#79#84#44#32#47#47#32#50#55#10#32#32#84+ - #82#73#71#71#69#82#95#69#70#70#69#67#84#44#32#47#47#32#50#56#10#32#32#84#82+ - #73#71#71#69#82#95#83#67#82#73#80#84#44#32#47#47#32#50#57#10#32#32#47#47#10+ - #32#32#84#82#73#71#71#69#82#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#47+ - #47#32#34#97#115#32#88#88#88#34#32#109#101#97#110#115#32#34#103#101#110#101+ - #114#97#116#101#32#116#104#105#115#32#105#100#101#110#116#105#102#105#101+ - #114#32#102#111#114#32#112#97#115#99#97#108#32#115#111#117#114#99#101#115#10+ - #98#105#116#115#101#116#32#80#97#110#101#108#84#121#112#101#32#123#10#32#32+ - #80#65#78#69#76#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65+ - #78#69#76#95#87#65#76#76#44#32#47#47#32#49#10#32#32#80#65#78#69#76#95#66#65+ - #67#75#44#32#47#47#32#50#10#32#32#80#65#78#69#76#95#70#79#82#69#44#32#47#47+ - #32#52#10#32#32#80#65#78#69#76#95#87#65#84#69#82#44#32#47#47#32#56#10#32#32+ - #80#65#78#69#76#95#65#67#73#68#49#44#32#47#47#32#49#54#10#32#32#80#65#78#69+ - #76#95#65#67#73#68#50#44#32#47#47#32#51#50#10#32#32#80#65#78#69#76#95#83#84+ - #69#80#44#32#47#47#32#54#52#10#32#32#80#65#78#69#76#95#76#73#70#84#85#80#44+ - #32#47#47#32#49#50#56#10#32#32#80#65#78#69#76#95#76#73#70#84#68#79#87#78#44+ - #32#47#47#32#50#53#54#10#32#32#80#65#78#69#76#95#79#80#69#78#68#79#79#82#44+ - #32#47#47#32#53#49#50#10#32#32#80#65#78#69#76#95#67#76#79#83#69#68#79#79#82+ - #44#32#47#47#32#49#48#50#52#10#32#32#80#65#78#69#76#95#66#76#79#67#75#77#79+ - #78#44#32#47#47#32#50#48#52#56#10#32#32#80#65#78#69#76#95#76#73#70#84#76#69+ - #70#84#44#32#47#47#32#52#48#57#54#10#32#32#80#65#78#69#76#95#76#73#70#84#82+ - #73#71#72#84#44#32#47#47#32#56#49#57#50#10#125#10#10#98#105#116#115#101#116+ - #32#80#97#110#101#108#70#108#97#103#32#123#10#32#32#80#65#78#69#76#95#70#76+ - #65#71#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65#78#69#76+ - #95#70#76#65#71#95#66#76#69#78#68#73#78#71#44#32#47#47#32#49#10#32#32#80#65+ - #78#69#76#95#70#76#65#71#95#72#73#68#69#44#32#47#47#32#50#10#32#32#80#65#78+ - #69#76#95#70#76#65#71#95#87#65#84#69#82#84#69#88#84#85#82#69#83#44#32#47#47+ - #32#52#10#125#10#10#101#110#117#109#32#69#102#102#101#99#116#65#99#116#105+ - #111#110#32#123#10#32#32#69#70#70#69#67#84#95#78#79#78#69#44#32#47#47#32#48+ - #10#32#32#69#70#70#69#67#84#95#84#69#76#69#80#79#82#84#44#32#47#47#32#49#10+ - #32#32#69#70#70#69#67#84#95#82#69#83#80#65#87#78#44#32#47#47#32#50#10#32#32+ - #69#70#70#69#67#84#95#70#73#82#69#44#32#47#47#32#51#10#125#10#10#101#110#117+ - #109#32#73#116#101#109#32#123#10#32#32#73#84#69#77#95#78#79#78#69#44#32#47+ - #47#32#48#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#83#77#65#76#76#44#32+ - #47#47#32#49#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#76#65#82#71#69#44+ - #32#47#47#32#50#10#32#32#73#84#69#77#95#77#69#68#75#73#84#95#66#76#65#67#75+ - #44#32#47#47#32#51#10#32#32#73#84#69#77#95#65#82#77#79#82#95#71#82#69#69#78+ - #44#32#47#47#32#52#10#32#32#73#84#69#77#95#65#82#77#79#82#95#66#76#85#69#44+ - #32#47#47#32#53#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#66#76#85#69#44+ - #32#47#47#32#54#10#32#32#73#84#69#77#95#83#80#72#69#82#69#95#87#72#73#84#69+ - #44#32#47#47#32#55#10#32#32#73#84#69#77#95#83#85#73#84#44#32#47#47#32#56#10+ - #32#32#73#84#69#77#95#79#88#89#71#69#78#44#32#47#47#32#57#10#32#32#73#84#69+ - #77#95#73#78#86#85#76#44#32#47#47#32#49#48#10#32#32#73#84#69#77#95#87#69#65+ - #80#79#78#95#83#65#87#44#32#47#47#32#49#49#10#32#32#73#84#69#77#95#87#69#65+ - #80#79#78#95#83#72#79#84#71#85#78#49#44#32#47#47#32#49#50#10#32#32#73#84#69+ - #77#95#87#69#65#80#79#78#95#83#72#79#84#71#85#78#50#44#32#47#47#32#49#51#10+ - #32#32#73#84#69#77#95#87#69#65#80#79#78#95#67#72#65#73#78#71#85#78#44#32#47+ - #47#32#49#52#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#82#79#67#75#69#84+ - #76#65#85#78#67#72#69#82#44#32#47#47#32#49#53#10#32#32#73#84#69#77#95#87#69+ - #65#80#79#78#95#80#76#65#83#77#65#44#32#47#47#32#49#54#10#32#32#73#84#69#77+ - #95#87#69#65#80#79#78#95#66#70#71#44#32#47#47#32#49#55#10#32#32#73#84#69#77+ - #95#87#69#65#80#79#78#95#83#85#80#69#82#80#85#76#69#77#69#84#44#32#47#47#32+ - #49#56#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76#69#84#83#44#32#47+ - #47#32#49#57#10#32#32#73#84#69#77#95#65#77#77#79#95#66#85#76#76#69#84#83#95+ - #66#79#88#44#32#47#47#32#50#48#10#32#32#73#84#69#77#95#65#77#77#79#95#83#72+ - #69#76#76#83#44#32#47#47#32#50#49#10#32#32#73#84#69#77#95#65#77#77#79#95#83+ - #72#69#76#76#83#95#66#79#88#44#32#47#47#32#50#50#10#32#32#73#84#69#77#95#65+ - #77#77#79#95#82#79#67#75#69#84#44#32#47#47#32#50#51#10#32#32#73#84#69#77#95+ - #65#77#77#79#95#82#79#67#75#69#84#95#66#79#88#44#32#47#47#32#50#52#10#32#32+ - #73#84#69#77#95#65#77#77#79#95#67#69#76#76#44#32#47#47#32#50#53#10#32#32#73+ - #84#69#77#95#65#77#77#79#95#67#69#76#76#95#66#73#71#44#32#47#47#32#50#54#10+ - #32#32#73#84#69#77#95#65#77#77#79#95#66#65#67#75#80#65#67#75#44#32#47#47#32+ - #50#55#10#32#32#73#84#69#77#95#75#69#89#95#82#69#68#44#32#47#47#32#50#56#10+ - #32#32#73#84#69#77#95#75#69#89#95#71#82#69#69#78#44#32#47#47#32#50#57#10#32+ - #32#73#84#69#77#95#75#69#89#95#66#76#85#69#44#32#47#47#32#51#48#10#32#32#73+ - #84#69#77#95#87#69#65#80#79#78#95#75#65#83#84#69#84#44#32#47#47#32#51#49#10+ - #32#32#73#84#69#77#95#87#69#65#80#79#78#95#80#73#83#84#79#76#44#32#47#47#32+ - #51#50#10#32#32#73#84#69#77#95#66#79#84#84#76#69#44#32#47#47#32#51#51#10#32+ - #32#73#84#69#77#95#72#69#76#77#69#84#44#32#47#47#32#51#52#10#32#32#73#84#69+ - #77#95#74#69#84#80#65#67#75#44#32#47#47#32#51#53#10#32#32#73#84#69#77#95#73+ - #78#86#73#83#44#32#47#47#32#51#54#10#32#32#73#84#69#77#95#87#69#65#80#79#78+ - #95#70#76#65#77#69#84#72#82#79#87#69#82#44#32#47#47#32#51#55#10#32#32#73#84+ - #69#77#95#65#77#77#79#95#70#85#69#76#67#65#78#44#32#47#47#32#51#56#10#32#32+ - #47#47#10#32#32#73#84#69#77#95#77#65#88#32#61#32#77#65#88#44#32#47#47#32#115+ - #116#111#114#101#32#116#104#101#32#108#97#115#116#32#105#116#101#109#39#115+ - #32#105#100#32#105#110#32#104#101#114#101#32#117#115#101#32#116#104#105#115+ - #32#105#110#32#102#111#114#32#108#111#111#112#115#10#125#10#10#98#105#116+ - #115#101#116#32#73#116#101#109#79#112#116#105#111#110#32#123#10#32#32#73#84+ - #69#77#95#79#80#84#73#79#78#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10+ - #32#32#73#84#69#77#95#79#80#84#73#79#78#95#79#78#76#89#68#77#44#32#47#47#32+ - #49#10#32#32#73#84#69#77#95#79#80#84#73#79#78#95#70#65#76#76#44#32#47#47#32+ - #50#10#125#10#10#101#110#117#109#32#65#114#101#97#84#121#112#101#32#123#10+ - #32#32#65#82#69#65#95#78#79#78#69#44#32#47#47#32#48#10#32#32#65#82#69#65#95+ - #80#76#65#89#69#82#80#79#73#78#84#49#44#32#47#47#32#49#10#32#32#65#82#69#65+ - #95#80#76#65#89#69#82#80#79#73#78#84#50#44#32#47#47#32#50#10#32#32#65#82#69+ - #65#95#68#77#80#79#73#78#84#44#32#47#47#32#51#10#32#32#65#82#69#65#95#82#69+ - #68#70#76#65#71#44#32#47#47#32#52#10#32#32#65#82#69#65#95#66#76#85#69#70#76+ - #65#71#44#32#47#47#32#53#10#32#32#65#82#69#65#95#68#79#77#70#76#65#71#44#32+ - #47#47#32#54#10#32#32#65#82#69#65#95#82#69#68#84#69#65#77#80#79#73#78#84#44+ - #32#47#47#32#55#10#32#32#65#82#69#65#95#66#76#85#69#84#69#65#77#80#79#73#78+ - #84#44#32#47#47#32#56#10#125#10#10#101#110#117#109#32#77#111#110#115#116#101+ - #114#32#123#10#32#32#77#79#78#83#84#69#82#95#78#79#78#69#44#32#47#47#32#48+ - #10#32#32#77#79#78#83#84#69#82#95#68#69#77#79#78#44#32#47#47#32#49#10#32#32+ - #77#79#78#83#84#69#82#95#73#77#80#44#32#47#47#32#50#10#32#32#77#79#78#83#84+ - #69#82#95#90#79#77#66#89#44#32#47#47#32#51#10#32#32#77#79#78#83#84#69#82#95+ - #83#69#82#71#44#32#47#47#32#52#10#32#32#77#79#78#83#84#69#82#95#67#89#66#69+ - #82#44#32#47#47#32#53#10#32#32#77#79#78#83#84#69#82#95#67#71#85#78#44#32#47+ - #47#32#54#10#32#32#77#79#78#83#84#69#82#95#66#65#82#79#78#44#32#47#47#32#55+ - #10#32#32#77#79#78#83#84#69#82#95#75#78#73#71#72#84#44#32#47#47#32#56#10#32+ - #32#77#79#78#83#84#69#82#95#67#65#67#79#44#32#47#47#32#57#10#32#32#77#79#78+ - #83#84#69#82#95#83#79#85#76#44#32#47#47#32#49#48#10#32#32#77#79#78#83#84#69+ - #82#95#80#65#73#78#44#32#47#47#32#49#49#10#32#32#77#79#78#83#84#69#82#95#83+ - #80#73#68#69#82#44#32#47#47#32#49#50#10#32#32#77#79#78#83#84#69#82#95#66#83+ - #80#44#32#47#47#32#49#51#10#32#32#77#79#78#83#84#69#82#95#77#65#78#67#85#66+ - #44#32#47#47#32#49#52#10#32#32#77#79#78#83#84#69#82#95#83#75#69#76#44#32#47+ - #47#32#49#53#10#32#32#77#79#78#83#84#69#82#95#86#73#76#69#44#32#47#47#32#49+ - #54#10#32#32#77#79#78#83#84#69#82#95#70#73#83#72#44#32#47#47#32#49#55#10#32+ - #32#77#79#78#83#84#69#82#95#66#65#82#82#69#76#44#32#47#47#32#49#56#10#32#32+ - #77#79#78#83#84#69#82#95#82#79#66#79#44#32#47#47#32#49#57#10#32#32#77#79#78+ - #83#84#69#82#95#77#65#78#44#32#47#47#32#50#48#10#32#32#47#47#32#97#108#105+ - #97#115#101#115#32#40#102#105#120#109#101#58#32#105#116#32#115#104#111#117+ - #108#100#32#98#101#32#96#77#79#78#83#84#69#82#95#90#79#77#66#73#69#32#61#32+ - #77#79#78#83#84#69#82#95#90#79#77#66#89#96#33#41#10#32#32#77#79#78#83#84#69+ - #82#95#90#79#77#66#73#69#32#61#32#51#44#10#125#10#10#101#110#117#109#32#77+ - #111#110#115#116#101#114#66#101#104#97#118#105#111#117#114#32#123#10#32#32+ - #66#72#95#78#79#82#77#65#76#44#32#47#47#32#48#10#32#32#66#72#95#75#73#76#76+ - #69#82#44#32#47#47#32#49#10#32#32#66#72#95#77#65#78#73#65#67#44#32#47#47#32+ - #50#10#32#32#66#72#95#73#78#83#65#78#69#44#32#47#47#32#51#10#32#32#66#72#95+ - #67#65#78#78#73#66#65#76#44#32#47#47#32#52#10#32#32#66#72#95#71#79#79#68#44+ - #32#47#47#32#53#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101#114+ - #83#104#111#116#32#123#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#80#73+ - #83#84#79#76#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ - #95#66#85#76#76#69#84#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83+ - #72#79#84#95#83#72#79#84#71#85#78#44#32#47#47#32#50#10#32#32#84#82#73#71#71+ - #69#82#95#83#72#79#84#95#83#83#71#44#32#47#47#32#51#10#32#32#84#82#73#71#71+ - #69#82#95#83#72#79#84#95#73#77#80#44#32#47#47#32#52#10#32#32#84#82#73#71#71+ - #69#82#95#83#72#79#84#95#80#76#65#83#77#65#44#32#47#47#32#53#10#32#32#84#82+ - #73#71#71#69#82#95#83#72#79#84#95#83#80#73#68#69#82#44#32#47#47#32#54#10#32+ - #32#84#82#73#71#71#69#82#95#83#72#79#84#95#67#65#67#79#44#32#47#47#32#55#10+ - #32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#65#82#79#78#44#32#47#47#32+ - #56#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#77#65#78#67#85#66#44#32+ - #47#47#32#57#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#82#69#86#44#32+ - #47#47#32#49#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#82#79#67#75+ - #69#84#44#32#47#47#32#49#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95+ - #66#70#71#44#32#47#47#32#49#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ - #95#69#88#80#76#44#32#47#47#32#49#51#10#32#32#84#82#73#71#71#69#82#95#83#72+ - #79#84#95#66#70#71#69#88#80#76#44#32#47#47#32#49#52#10#32#32#47#47#10#32#32+ - #84#82#73#71#71#69#82#95#83#72#79#84#95#77#65#88#32#61#32#77#65#88#44#10#125+ - #10#10#101#110#117#109#32#84#114#105#103#103#101#114#83#104#111#116#84#97+ - #114#103#101#116#32#123#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84+ - #65#82#71#69#84#95#78#79#78#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69+ - #82#95#83#72#79#84#95#84#65#82#71#69#84#95#77#79#78#44#32#47#47#32#49#10#32+ - #32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#44+ - #32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71+ - #69#84#95#82#69#68#44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72+ - #79#84#95#84#65#82#71#69#84#95#66#76#85#69#44#32#47#47#32#52#10#32#32#84#82+ - #73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#77#79#78#80#76#82#44+ - #32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71+ - #69#84#95#80#76#82#77#79#78#44#32#47#47#32#54#10#125#10#10#101#110#117#109+ - #32#84#114#105#103#103#101#114#83#104#111#116#65#105#109#32#123#10#32#32#84+ - #82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#68#69#70#65#85#76#84#44#32+ - #47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#65+ - #76#76#77#65#80#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79+ - #84#95#65#73#77#95#84#82#65#67#69#44#32#47#47#32#50#10#32#32#84#82#73#71#71+ - #69#82#95#83#72#79#84#95#65#73#77#95#84#82#65#67#69#65#76#76#44#32#47#47#32+ - #51#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101#114#69#102#102+ - #101#99#116#32#123#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80+ - #65#82#84#73#67#76#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69+ - #70#70#69#67#84#95#65#78#73#77#65#84#73#79#78#44#32#47#47#32#49#10#125#10#10+ - #101#110#117#109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#84#121+ - #112#101#32#123#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#83#76+ - #73#81#85#73#68#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70+ - #69#67#84#95#76#76#73#81#85#73#68#44#32#47#47#32#49#10#32#32#84#82#73#71#71+ - #69#82#95#69#70#70#69#67#84#95#68#76#73#81#85#73#68#44#32#47#47#32#50#10#32+ - #32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#66#76#79#79#68#44#32#47#47+ - #32#51#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#83#80#65#82#75+ - #44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#66+ - #85#66#66#76#69#44#32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#69#70#70+ - #69#67#84#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#101#110#117#109#32+ - #84#114#105#103#103#101#114#69#102#102#101#99#116#80#111#115#32#123#10#32#32+ - #84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#79#83#95#67#69#78#84#69#82+ - #44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80+ - #79#83#95#65#82#69#65#44#32#47#47#32#49#10#125#10#10#101#110#117#109#32#84+ - #114#105#103#103#101#114#77#117#115#105#99#65#99#116#105#111#110#32#123#10+ - #32#32#84#82#73#71#71#69#82#95#77#85#83#73#67#95#65#67#84#73#79#78#95#83#84+ - #79#80#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67#95+ - #65#67#84#73#79#78#95#80#76#65#89#44#32#47#47#32#49#59#32#117#110#112#97#117+ - #115#101#32#111#114#32#114#101#115#116#97#114#116#10#125#10#10#101#110#117+ - #109#32#84#114#105#103#103#101#114#83#99#111#114#101#65#99#116#105#111#110+ - #32#123#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#65#67#84#73#79#78+ - #95#65#68#68#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82+ - #69#95#65#67#84#73#79#78#95#83#85#66#44#32#47#47#32#49#10#32#32#84#82#73#71+ - #71#69#82#95#83#67#79#82#69#95#65#67#84#73#79#78#95#87#73#78#44#32#47#47#32+ - #50#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#65#67#84#73#79#78#95+ - #76#79#79#83#69#44#32#47#47#32#51#10#125#10#10#101#110#117#109#32#84#114#105+ - #103#103#101#114#77#101#115#115#97#103#101#68#101#115#116#32#123#10#32#32#84+ - #82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68#69#83#84#95#77#69#44#32#47+ - #47#32#48#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68#69#83+ - #84#95#77#89#95#84#69#65#77#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82+ - #95#77#69#83#83#65#71#69#95#68#69#83#84#95#69#78#69#77#89#95#84#69#65#77#44+ - #32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68+ - #69#83#84#95#82#69#68#95#84#69#65#77#44#32#47#47#32#51#10#32#32#84#82#73#71+ - #71#69#82#95#77#69#83#83#65#71#69#95#68#69#83#84#95#66#76#85#69#95#84#69#65+ - #77#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69+ - #95#68#69#83#84#95#69#86#69#82#89#79#78#69#44#32#47#47#32#53#10#125#10#10+ - #101#110#117#109#32#84#114#105#103#103#101#114#77#101#115#115#97#103#101#75+ - #105#110#100#32#123#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95+ - #75#73#78#68#95#67#72#65#84#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82+ - #95#77#69#83#83#65#71#69#95#75#73#78#68#95#71#65#77#69#44#32#47#47#32#49#10+ - #125#10#10#98#105#116#115#101#116#32#65#99#116#105#118#97#116#101#84#121#112+ - #101#32#123#10#32#32#65#67#84#73#86#65#84#69#95#78#79#78#69#32#61#32#48#44+ - #32#47#47#32#48#10#32#32#65#67#84#73#86#65#84#69#95#80#76#65#89#69#82#67#79+ - #76#76#73#68#69#44#32#47#47#32#49#10#32#32#65#67#84#73#86#65#84#69#95#77#79+ - #78#83#84#69#82#67#79#76#76#73#68#69#44#32#47#47#32#50#10#32#32#65#67#84#73+ - #86#65#84#69#95#80#76#65#89#69#82#80#82#69#83#83#44#32#47#47#32#52#10#32#32+ - #65#67#84#73#86#65#84#69#95#77#79#78#83#84#69#82#80#82#69#83#83#44#32#47#47+ - #32#56#10#32#32#65#67#84#73#86#65#84#69#95#83#72#79#84#44#32#47#47#32#49#54+ - #10#32#32#65#67#84#73#86#65#84#69#95#78#79#77#79#78#83#84#69#82#44#32#47#47+ - #32#51#50#10#32#32#65#67#84#73#86#65#84#69#95#67#85#83#84#79#77#32#61#32#50+ - #53#53#44#32#47#47#32#110#111#116#101#32#116#104#97#116#32#34#100#105#114+ - #101#99#116#32#97#115#115#105#103#110#34#32#102#105#101#108#100#32#100#111+ - #101#115#110#39#116#32#97#102#102#101#99#116#32#98#105#116#32#99#111#117#110+ - #116#101#114#10#125#10#10#98#105#116#115#101#116#32#75#101#121#32#123#10#32+ - #32#75#69#89#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#75#69#89+ - #95#82#69#68#44#32#47#47#32#49#10#32#32#75#69#89#95#71#82#69#69#78#44#32#47+ - #47#32#50#10#32#32#75#69#89#95#66#76#85#69#44#32#47#47#32#52#10#32#32#75#69+ - #89#95#82#69#68#84#69#65#77#44#32#47#47#32#56#10#32#32#75#69#89#95#66#76#85+ - #69#84#69#65#77#44#32#47#47#32#49#54#10#125#10#10#10#47#47#47#47#47#47#47#47+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ + #47#47#10#47#47#32#115#112#101#99#105#97#108#32#116#101#120#116#117#114#101+ + #32#105#100#101#110#116#105#102#105#101#114#115#44#32#117#115#101#100#32#116+ + #111#32#103#101#110#101#114#97#116#101#32#112#97#115#99#97#108#32#115#111+ + #117#114#99#101#115#10#101#110#117#109#32#84#101#120#116#117#114#101#83#112+ + #101#99#105#97#108#32#123#10#32#32#84#69#88#84#85#82#69#95#83#80#69#67#73#65+ + #76#95#87#65#84#69#82#32#61#32#45#49#44#10#32#32#84#69#88#84#85#82#69#95#83+ + #80#69#67#73#65#76#95#65#67#73#68#49#32#61#32#45#50#44#10#32#32#84#69#88#84+ + #85#82#69#95#83#80#69#67#73#65#76#95#65#67#73#68#50#32#61#32#45#51#44#10#32+ + #32#84#69#88#84#85#82#69#95#78#79#78#69#32#61#32#45#52#44#10#125#10#10#47#47+ + #32#100#105#114#101#99#116#105#111#110#115#10#101#110#117#109#32#68#105#114+ + #84#121#112#101#32#123#10#32#32#68#73#82#95#76#69#70#84#44#32#47#47#32#48#10+ + #32#32#68#73#82#95#82#73#71#72#84#44#32#47#47#32#49#10#32#32#68#73#82#95#83+ + #79#77#69#84#72#73#78#71#50#44#32#47#47#32#50#10#125#10#10#47#47#32#116#114+ + #105#103#103#101#114#115#10#101#110#117#109#32#84#114#105#103#103#101#114#84+ + #121#112#101#32#123#10#32#32#84#82#73#71#71#69#82#95#78#79#78#69#44#32#47#47+ + #32#48#10#32#32#84#82#73#71#71#69#82#95#69#88#73#84#44#32#47#47#32#49#10#32+ + #32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84#44#32#47#47#32#50#10#32+ + #32#84#82#73#71#71#69#82#95#79#80#69#78#68#79#79#82#44#32#47#47#32#51#10#32+ + #32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79#82#44#32#47#47#32#52#10+ + #32#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#47#47#32#53#10#32#32#84#82+ + #73#71#71#69#82#95#68#79#79#82#53#44#32#47#47#32#54#10#32#32#84#82#73#71#71+ + #69#82#95#67#76#79#83#69#84#82#65#80#44#32#47#47#32#55#10#32#32#84#82#73#71+ + #71#69#82#95#84#82#65#80#44#32#47#47#32#56#10#32#32#84#82#73#71#71#69#82#95+ + #80#82#69#83#83#44#32#47#47#32#57#10#32#32#84#82#73#71#71#69#82#95#83#69#67+ + #82#69#84#44#32#47#47#32#49#48#10#32#32#84#82#73#71#71#69#82#95#76#73#70#84+ + #85#80#44#32#47#47#32#49#49#10#32#32#84#82#73#71#71#69#82#95#76#73#70#84#68+ + #79#87#78#44#32#47#47#32#49#50#10#32#32#84#82#73#71#71#69#82#95#76#73#70#84+ + #44#32#47#47#32#49#51#10#32#32#84#82#73#71#71#69#82#95#84#69#88#84#85#82#69+ + #44#32#47#47#32#49#52#10#32#32#84#82#73#71#71#69#82#95#79#78#44#32#47#47#32+ + #49#53#10#32#32#84#82#73#71#71#69#82#95#79#70#70#44#32#47#47#32#49#54#10#32+ + #32#84#82#73#71#71#69#82#95#79#78#79#70#70#44#32#47#47#32#49#55#10#32#32#84+ + #82#73#71#71#69#82#95#83#79#85#78#68#44#32#47#47#32#49#56#10#32#32#84#82#73+ + #71#71#69#82#95#83#80#65#87#78#77#79#78#83#84#69#82#44#32#47#47#32#49#57#10+ + #32#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84#69#77#44#32#47#47#32#50+ + #48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67#44#32#47#47#32#50#49#10+ + #32#32#84#82#73#71#71#69#82#95#80#85#83#72#44#32#47#47#32#50#50#10#32#32#84+ + #82#73#71#71#69#82#95#83#67#79#82#69#44#32#47#47#32#50#51#10#32#32#84#82#73+ + #71#71#69#82#95#77#69#83#83#65#71#69#44#32#47#47#32#50#52#10#32#32#84#82#73+ + #71#71#69#82#95#68#65#77#65#71#69#44#32#47#47#32#50#53#10#32#32#84#82#73#71+ + #71#69#82#95#72#69#65#76#84#72#44#32#47#47#32#50#54#10#32#32#84#82#73#71#71+ + #69#82#95#83#72#79#84#44#32#47#47#32#50#55#10#32#32#84#82#73#71#71#69#82#95+ + #69#70#70#69#67#84#44#32#47#47#32#50#56#10#32#32#84#82#73#71#71#69#82#95#83+ + #67#82#73#80#84#44#32#47#47#32#50#57#10#32#32#47#47#10#32#32#84#82#73#71#71+ + #69#82#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#47#47#32#34#97#115#32+ + #88#88#88#34#32#109#101#97#110#115#32#34#103#101#110#101#114#97#116#101#32+ + #116#104#105#115#32#105#100#101#110#116#105#102#105#101#114#32#102#111#114+ + #32#112#97#115#99#97#108#32#115#111#117#114#99#101#115#10#98#105#116#115#101+ + #116#32#80#97#110#101#108#84#121#112#101#32#123#10#32#32#80#65#78#69#76#95+ + #78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65#78#69#76#95#87#65+ + #76#76#44#32#47#47#32#49#10#32#32#80#65#78#69#76#95#66#65#67#75#44#32#47#47+ + #32#50#10#32#32#80#65#78#69#76#95#70#79#82#69#44#32#47#47#32#52#10#32#32#80+ + #65#78#69#76#95#87#65#84#69#82#44#32#47#47#32#56#10#32#32#80#65#78#69#76#95+ + #65#67#73#68#49#44#32#47#47#32#49#54#10#32#32#80#65#78#69#76#95#65#67#73#68+ + #50#44#32#47#47#32#51#50#10#32#32#80#65#78#69#76#95#83#84#69#80#44#32#47#47+ + #32#54#52#10#32#32#80#65#78#69#76#95#76#73#70#84#85#80#44#32#47#47#32#49#50+ + #56#10#32#32#80#65#78#69#76#95#76#73#70#84#68#79#87#78#44#32#47#47#32#50#53+ + #54#10#32#32#80#65#78#69#76#95#79#80#69#78#68#79#79#82#44#32#47#47#32#53#49+ + #50#10#32#32#80#65#78#69#76#95#67#76#79#83#69#68#79#79#82#44#32#47#47#32#49+ + #48#50#52#10#32#32#80#65#78#69#76#95#66#76#79#67#75#77#79#78#44#32#47#47#32+ + #50#48#52#56#10#32#32#80#65#78#69#76#95#76#73#70#84#76#69#70#84#44#32#47#47+ + #32#52#48#57#54#10#32#32#80#65#78#69#76#95#76#73#70#84#82#73#71#72#84#44#32+ + #47#47#32#56#49#57#50#10#125#10#10#98#105#116#115#101#116#32#80#97#110#101+ + #108#70#108#97#103#32#123#10#32#32#80#65#78#69#76#95#70#76#65#71#95#78#79#78+ + #69#32#61#32#48#44#32#47#47#32#48#10#32#32#80#65#78#69#76#95#70#76#65#71#95+ + #66#76#69#78#68#73#78#71#44#32#47#47#32#49#10#32#32#80#65#78#69#76#95#70#76+ + #65#71#95#72#73#68#69#44#32#47#47#32#50#10#32#32#80#65#78#69#76#95#70#76#65+ + #71#95#87#65#84#69#82#84#69#88#84#85#82#69#83#44#32#47#47#32#52#10#125#10#10+ + #101#110#117#109#32#69#102#102#101#99#116#65#99#116#105#111#110#32#123#10#32+ + #32#69#70#70#69#67#84#95#78#79#78#69#44#32#47#47#32#48#10#32#32#69#70#70#69+ + #67#84#95#84#69#76#69#80#79#82#84#44#32#47#47#32#49#10#32#32#69#70#70#69#67+ + #84#95#82#69#83#80#65#87#78#44#32#47#47#32#50#10#32#32#69#70#70#69#67#84#95+ + #70#73#82#69#44#32#47#47#32#51#10#125#10#10#101#110#117#109#32#73#116#101+ + #109#32#123#10#32#32#73#84#69#77#95#78#79#78#69#44#32#47#47#32#48#10#32#32+ + #73#84#69#77#95#77#69#68#75#73#84#95#83#77#65#76#76#44#32#47#47#32#49#10#32+ + #32#73#84#69#77#95#77#69#68#75#73#84#95#76#65#82#71#69#44#32#47#47#32#50#10+ + #32#32#73#84#69#77#95#77#69#68#75#73#84#95#66#76#65#67#75#44#32#47#47#32#51+ + #10#32#32#73#84#69#77#95#65#82#77#79#82#95#71#82#69#69#78#44#32#47#47#32#52+ + #10#32#32#73#84#69#77#95#65#82#77#79#82#95#66#76#85#69#44#32#47#47#32#53#10+ + #32#32#73#84#69#77#95#83#80#72#69#82#69#95#66#76#85#69#44#32#47#47#32#54#10+ + #32#32#73#84#69#77#95#83#80#72#69#82#69#95#87#72#73#84#69#44#32#47#47#32#55+ + #10#32#32#73#84#69#77#95#83#85#73#84#44#32#47#47#32#56#10#32#32#73#84#69#77+ + #95#79#88#89#71#69#78#44#32#47#47#32#57#10#32#32#73#84#69#77#95#73#78#86#85+ + #76#44#32#47#47#32#49#48#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#83#65+ + #87#44#32#47#47#32#49#49#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#83#72+ + #79#84#71#85#78#49#44#32#47#47#32#49#50#10#32#32#73#84#69#77#95#87#69#65#80+ + #79#78#95#83#72#79#84#71#85#78#50#44#32#47#47#32#49#51#10#32#32#73#84#69#77+ + #95#87#69#65#80#79#78#95#67#72#65#73#78#71#85#78#44#32#47#47#32#49#52#10#32+ + #32#73#84#69#77#95#87#69#65#80#79#78#95#82#79#67#75#69#84#76#65#85#78#67#72+ + #69#82#44#32#47#47#32#49#53#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#80+ + #76#65#83#77#65#44#32#47#47#32#49#54#10#32#32#73#84#69#77#95#87#69#65#80#79+ + #78#95#66#70#71#44#32#47#47#32#49#55#10#32#32#73#84#69#77#95#87#69#65#80#79+ + #78#95#83#85#80#69#82#80#85#76#69#77#69#84#44#32#47#47#32#49#56#10#32#32#73+ + #84#69#77#95#65#77#77#79#95#66#85#76#76#69#84#83#44#32#47#47#32#49#57#10#32+ + #32#73#84#69#77#95#65#77#77#79#95#66#85#76#76#69#84#83#95#66#79#88#44#32#47+ + #47#32#50#48#10#32#32#73#84#69#77#95#65#77#77#79#95#83#72#69#76#76#83#44#32+ + #47#47#32#50#49#10#32#32#73#84#69#77#95#65#77#77#79#95#83#72#69#76#76#83#95+ + #66#79#88#44#32#47#47#32#50#50#10#32#32#73#84#69#77#95#65#77#77#79#95#82#79+ + #67#75#69#84#44#32#47#47#32#50#51#10#32#32#73#84#69#77#95#65#77#77#79#95#82+ + #79#67#75#69#84#95#66#79#88#44#32#47#47#32#50#52#10#32#32#73#84#69#77#95#65+ + #77#77#79#95#67#69#76#76#44#32#47#47#32#50#53#10#32#32#73#84#69#77#95#65#77+ + #77#79#95#67#69#76#76#95#66#73#71#44#32#47#47#32#50#54#10#32#32#73#84#69#77+ + #95#65#77#77#79#95#66#65#67#75#80#65#67#75#44#32#47#47#32#50#55#10#32#32#73+ + #84#69#77#95#75#69#89#95#82#69#68#44#32#47#47#32#50#56#10#32#32#73#84#69#77+ + #95#75#69#89#95#71#82#69#69#78#44#32#47#47#32#50#57#10#32#32#73#84#69#77#95+ + #75#69#89#95#66#76#85#69#44#32#47#47#32#51#48#10#32#32#73#84#69#77#95#87#69+ + #65#80#79#78#95#75#65#83#84#69#84#44#32#47#47#32#51#49#10#32#32#73#84#69#77+ + #95#87#69#65#80#79#78#95#80#73#83#84#79#76#44#32#47#47#32#51#50#10#32#32#73+ + #84#69#77#95#66#79#84#84#76#69#44#32#47#47#32#51#51#10#32#32#73#84#69#77#95+ + #72#69#76#77#69#84#44#32#47#47#32#51#52#10#32#32#73#84#69#77#95#74#69#84#80+ + #65#67#75#44#32#47#47#32#51#53#10#32#32#73#84#69#77#95#73#78#86#73#83#44#32+ + #47#47#32#51#54#10#32#32#73#84#69#77#95#87#69#65#80#79#78#95#70#76#65#77#69+ + #84#72#82#79#87#69#82#44#32#47#47#32#51#55#10#32#32#73#84#69#77#95#65#77#77+ + #79#95#70#85#69#76#67#65#78#44#32#47#47#32#51#56#10#32#32#47#47#10#32#32#73+ + #84#69#77#95#77#65#88#32#61#32#77#65#88#44#32#47#47#32#115#116#111#114#101+ + #32#116#104#101#32#108#97#115#116#32#105#116#101#109#39#115#32#105#100#32+ + #105#110#32#104#101#114#101#32#117#115#101#32#116#104#105#115#32#105#110#32+ + #102#111#114#32#108#111#111#112#115#10#125#10#10#98#105#116#115#101#116#32+ + #73#116#101#109#79#112#116#105#111#110#32#123#10#32#32#73#84#69#77#95#79#80+ + #84#73#79#78#95#78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#73#84#69+ + #77#95#79#80#84#73#79#78#95#79#78#76#89#68#77#44#32#47#47#32#49#10#32#32#73+ + #84#69#77#95#79#80#84#73#79#78#95#70#65#76#76#44#32#47#47#32#50#10#125#10#10+ + #101#110#117#109#32#65#114#101#97#84#121#112#101#32#123#10#32#32#65#82#69#65+ + #95#78#79#78#69#44#32#47#47#32#48#10#32#32#65#82#69#65#95#80#76#65#89#69#82+ + #80#79#73#78#84#49#44#32#47#47#32#49#10#32#32#65#82#69#65#95#80#76#65#89#69+ + #82#80#79#73#78#84#50#44#32#47#47#32#50#10#32#32#65#82#69#65#95#68#77#80#79+ + #73#78#84#44#32#47#47#32#51#10#32#32#65#82#69#65#95#82#69#68#70#76#65#71#44+ + #32#47#47#32#52#10#32#32#65#82#69#65#95#66#76#85#69#70#76#65#71#44#32#47#47+ + #32#53#10#32#32#65#82#69#65#95#68#79#77#70#76#65#71#44#32#47#47#32#54#10#32+ + #32#65#82#69#65#95#82#69#68#84#69#65#77#80#79#73#78#84#44#32#47#47#32#55#10+ + #32#32#65#82#69#65#95#66#76#85#69#84#69#65#77#80#79#73#78#84#44#32#47#47#32+ + #56#10#125#10#10#101#110#117#109#32#77#111#110#115#116#101#114#32#123#10#32+ + #32#77#79#78#83#84#69#82#95#78#79#78#69#44#32#47#47#32#48#10#32#32#77#79#78+ + #83#84#69#82#95#68#69#77#79#78#44#32#47#47#32#49#10#32#32#77#79#78#83#84#69+ + #82#95#73#77#80#44#32#47#47#32#50#10#32#32#77#79#78#83#84#69#82#95#90#79#77+ + #66#89#44#32#47#47#32#51#10#32#32#77#79#78#83#84#69#82#95#83#69#82#71#44#32+ + #47#47#32#52#10#32#32#77#79#78#83#84#69#82#95#67#89#66#69#82#44#32#47#47#32+ + #53#10#32#32#77#79#78#83#84#69#82#95#67#71#85#78#44#32#47#47#32#54#10#32#32+ + #77#79#78#83#84#69#82#95#66#65#82#79#78#44#32#47#47#32#55#10#32#32#77#79#78+ + #83#84#69#82#95#75#78#73#71#72#84#44#32#47#47#32#56#10#32#32#77#79#78#83#84+ + #69#82#95#67#65#67#79#44#32#47#47#32#57#10#32#32#77#79#78#83#84#69#82#95#83+ + #79#85#76#44#32#47#47#32#49#48#10#32#32#77#79#78#83#84#69#82#95#80#65#73#78+ + #44#32#47#47#32#49#49#10#32#32#77#79#78#83#84#69#82#95#83#80#73#68#69#82#44+ + #32#47#47#32#49#50#10#32#32#77#79#78#83#84#69#82#95#66#83#80#44#32#47#47#32+ + #49#51#10#32#32#77#79#78#83#84#69#82#95#77#65#78#67#85#66#44#32#47#47#32#49+ + #52#10#32#32#77#79#78#83#84#69#82#95#83#75#69#76#44#32#47#47#32#49#53#10#32+ + #32#77#79#78#83#84#69#82#95#86#73#76#69#44#32#47#47#32#49#54#10#32#32#77#79+ + #78#83#84#69#82#95#70#73#83#72#44#32#47#47#32#49#55#10#32#32#77#79#78#83#84+ + #69#82#95#66#65#82#82#69#76#44#32#47#47#32#49#56#10#32#32#77#79#78#83#84#69+ + #82#95#82#79#66#79#44#32#47#47#32#49#57#10#32#32#77#79#78#83#84#69#82#95#77+ + #65#78#44#32#47#47#32#50#48#10#32#32#47#47#32#97#108#105#97#115#101#115#32+ + #40#102#105#120#109#101#58#32#105#116#32#115#104#111#117#108#100#32#98#101+ + #32#96#77#79#78#83#84#69#82#95#90#79#77#66#73#69#32#61#32#77#79#78#83#84#69+ + #82#95#90#79#77#66#89#96#33#41#10#32#32#77#79#78#83#84#69#82#95#90#79#77#66+ + #73#69#32#61#32#51#44#10#125#10#10#101#110#117#109#32#77#111#110#115#116#101+ + #114#66#101#104#97#118#105#111#117#114#32#123#10#32#32#66#72#95#78#79#82#77+ + #65#76#44#32#47#47#32#48#10#32#32#66#72#95#75#73#76#76#69#82#44#32#47#47#32+ + #49#10#32#32#66#72#95#77#65#78#73#65#67#44#32#47#47#32#50#10#32#32#66#72#95+ + #73#78#83#65#78#69#44#32#47#47#32#51#10#32#32#66#72#95#67#65#78#78#73#66#65+ + #76#44#32#47#47#32#52#10#32#32#66#72#95#71#79#79#68#44#32#47#47#32#53#10#125+ + #10#10#101#110#117#109#32#84#114#105#103#103#101#114#83#104#111#116#32#123+ + #10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#80#73#83#84#79#76#44#32#47+ + #47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#85#76#76#69#84+ + #44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#83#72#79+ + #84#71#85#78#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ + #95#83#83#71#44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ + #95#73#77#80#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ + #95#80#76#65#83#77#65#44#32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#83+ + #72#79#84#95#83#80#73#68#69#82#44#32#47#47#32#54#10#32#32#84#82#73#71#71#69+ + #82#95#83#72#79#84#95#67#65#67#79#44#32#47#47#32#55#10#32#32#84#82#73#71#71+ + #69#82#95#83#72#79#84#95#66#65#82#79#78#44#32#47#47#32#56#10#32#32#84#82#73+ + #71#71#69#82#95#83#72#79#84#95#77#65#78#67#85#66#44#32#47#47#32#57#10#32#32+ + #84#82#73#71#71#69#82#95#83#72#79#84#95#82#69#86#44#32#47#47#32#49#48#10#32+ + #32#84#82#73#71#71#69#82#95#83#72#79#84#95#82#79#67#75#69#84#44#32#47#47#32+ + #49#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#44#32#47#47+ + #32#49#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#69#88#80#76#44#32+ + #47#47#32#49#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#66#70#71#69+ + #88#80#76#44#32#47#47#32#49#52#10#32#32#47#47#10#32#32#84#82#73#71#71#69#82+ + #95#83#72#79#84#95#77#65#88#32#61#32#77#65#88#44#10#125#10#10#101#110#117+ + #109#32#84#114#105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#32+ + #123#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#78+ + #79#78#69#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95+ + #84#65#82#71#69#84#95#77#79#78#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69+ + #82#95#83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#44#32#47#47#32#50#10#32+ + #32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#82#69#68#44+ + #32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71+ + #69#84#95#66#76#85#69#44#32#47#47#32#52#10#32#32#84#82#73#71#71#69#82#95#83+ + #72#79#84#95#84#65#82#71#69#84#95#77#79#78#80#76#82#44#32#47#47#32#53#10#32+ + #32#84#82#73#71#71#69#82#95#83#72#79#84#95#84#65#82#71#69#84#95#80#76#82#77+ + #79#78#44#32#47#47#32#54#10#125#10#10#101#110#117#109#32#84#114#105#103#103+ + #101#114#83#104#111#116#65#105#109#32#123#10#32#32#84#82#73#71#71#69#82#95+ + #83#72#79#84#95#65#73#77#95#68#69#70#65#85#76#84#44#32#47#47#32#48#10#32#32+ + #84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#65#76#76#77#65#80#44#32+ + #47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#84+ + #82#65#67#69#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#72#79#84+ + #95#65#73#77#95#84#82#65#67#69#65#76#76#44#32#47#47#32#51#10#125#10#10#101+ + #110#117#109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#32#123#10+ + #32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#65#82#84#73#67#76#69+ + #44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#65+ + #78#73#77#65#84#73#79#78#44#32#47#47#32#49#10#125#10#10#101#110#117#109#32+ + #84#114#105#103#103#101#114#69#102#102#101#99#116#84#121#112#101#32#123#10+ + #32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#83#76#73#81#85#73#68#44+ + #32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#76#76+ + #73#81#85#73#68#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#69#70#70+ + #69#67#84#95#68#76#73#81#85#73#68#44#32#47#47#32#50#10#32#32#84#82#73#71#71+ + #69#82#95#69#70#70#69#67#84#95#66#76#79#79#68#44#32#47#47#32#51#10#32#32#84+ + #82#73#71#71#69#82#95#69#70#70#69#67#84#95#83#80#65#82#75#44#32#47#47#32#52+ + #10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#66#85#66#66#76#69#44+ + #32#47#47#32#53#10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#77#65+ + #88#32#61#32#77#65#88#44#10#125#10#10#101#110#117#109#32#84#114#105#103#103+ + #101#114#69#102#102#101#99#116#80#111#115#32#123#10#32#32#84#82#73#71#71#69+ + #82#95#69#70#70#69#67#84#95#80#79#83#95#67#69#78#84#69#82#44#32#47#47#32#48+ + #10#32#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#79#83#95#65#82#69+ + #65#44#32#47#47#32#49#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101+ + #114#77#117#115#105#99#65#99#116#105#111#110#32#123#10#32#32#84#82#73#71#71+ + #69#82#95#77#85#83#73#67#95#65#67#84#73#79#78#95#83#84#79#80#44#32#47#47#32+ + #48#10#32#32#84#82#73#71#71#69#82#95#77#85#83#73#67#95#65#67#84#73#79#78#95+ + #80#76#65#89#44#32#47#47#32#49#59#32#117#110#112#97#117#115#101#32#111#114+ + #32#114#101#115#116#97#114#116#10#125#10#10#101#110#117#109#32#84#114#105+ + #103#103#101#114#83#99#111#114#101#65#99#116#105#111#110#32#123#10#32#32#84+ + #82#73#71#71#69#82#95#83#67#79#82#69#95#65#67#84#73#79#78#95#65#68#68#44#32+ + #47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#65#67#84#73+ + #79#78#95#83#85#66#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#83#67+ + #79#82#69#95#65#67#84#73#79#78#95#87#73#78#44#32#47#47#32#50#10#32#32#84#82+ + #73#71#71#69#82#95#83#67#79#82#69#95#65#67#84#73#79#78#95#76#79#79#83#69#44+ + #32#47#47#32#51#10#125#10#10#101#110#117#109#32#84#114#105#103#103#101#114+ + #77#101#115#115#97#103#101#68#101#115#116#32#123#10#32#32#84#82#73#71#71#69+ + #82#95#77#69#83#83#65#71#69#95#68#69#83#84#95#77#69#44#32#47#47#32#48#10#32+ + #32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68#69#83#84#95#77#89#95+ + #84#69#65#77#44#32#47#47#32#49#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83+ + #65#71#69#95#68#69#83#84#95#69#78#69#77#89#95#84#69#65#77#44#32#47#47#32#50+ + #10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68#69#83#84#95#82+ + #69#68#95#84#69#65#77#44#32#47#47#32#51#10#32#32#84#82#73#71#71#69#82#95#77+ + #69#83#83#65#71#69#95#68#69#83#84#95#66#76#85#69#95#84#69#65#77#44#32#47#47+ + #32#52#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#68#69#83#84+ + #95#69#86#69#82#89#79#78#69#44#32#47#47#32#53#10#125#10#10#101#110#117#109+ + #32#84#114#105#103#103#101#114#77#101#115#115#97#103#101#75#105#110#100#32+ + #123#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#95#75#73#78#68#95+ + #67#72#65#84#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#77#69#83#83+ + #65#71#69#95#75#73#78#68#95#71#65#77#69#44#32#47#47#32#49#10#125#10#10#98+ + #105#116#115#101#116#32#65#99#116#105#118#97#116#101#84#121#112#101#32#123+ + #10#32#32#65#67#84#73#86#65#84#69#95#78#79#78#69#32#61#32#48#44#32#47#47#32+ + #48#10#32#32#65#67#84#73#86#65#84#69#95#80#76#65#89#69#82#67#79#76#76#73#68+ + #69#44#32#47#47#32#49#10#32#32#65#67#84#73#86#65#84#69#95#77#79#78#83#84#69+ + #82#67#79#76#76#73#68#69#44#32#47#47#32#50#10#32#32#65#67#84#73#86#65#84#69+ + #95#80#76#65#89#69#82#80#82#69#83#83#44#32#47#47#32#52#10#32#32#65#67#84#73+ + #86#65#84#69#95#77#79#78#83#84#69#82#80#82#69#83#83#44#32#47#47#32#56#10#32+ + #32#65#67#84#73#86#65#84#69#95#83#72#79#84#44#32#47#47#32#49#54#10#32#32#65+ + #67#84#73#86#65#84#69#95#78#79#77#79#78#83#84#69#82#44#32#47#47#32#51#50#10+ + #32#32#65#67#84#73#86#65#84#69#95#67#85#83#84#79#77#32#61#32#50#53#53#44#32+ + #47#47#32#110#111#116#101#32#116#104#97#116#32#34#100#105#114#101#99#116#32+ + #97#115#115#105#103#110#34#32#102#105#101#108#100#32#100#111#101#115#110#39+ + #116#32#97#102#102#101#99#116#32#98#105#116#32#99#111#117#110#116#101#114#10+ + #125#10#10#98#105#116#115#101#116#32#75#101#121#32#123#10#32#32#75#69#89#95+ + #78#79#78#69#32#61#32#48#44#32#47#47#32#48#10#32#32#75#69#89#95#82#69#68#44+ + #32#47#47#32#49#10#32#32#75#69#89#95#71#82#69#69#78#44#32#47#47#32#50#10#32+ + #32#75#69#89#95#66#76#85#69#44#32#47#47#32#52#10#32#32#75#69#89#95#82#69#68+ + #84#69#65#77#44#32#47#47#32#56#10#32#32#75#69#89#95#66#76#85#69#84#69#65#77+ + #44#32#47#47#32#49#54#10#125#10#10#10#47#47#47#47#47#47#47#47#47#47#47#47#47+ #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ - #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#10#47#47+ - #32#118#97#114#105#111#117#115#32#116#114#105#103#103#101#114#115#10#84#114+ - #105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95+ - #69#88#73#84#32#123#10#32#32#34#109#97#112#34#32#116#121#112#101#32#99#104+ - #97#114#91#49#54#93#32#111#102#102#115#101#116#32#48#32#119#114#105#116#101+ - #100#101#102#97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97+ - #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84#32+ - #123#10#32#32#34#116#97#114#103#101#116#34#32#116#121#112#101#32#112#111#105+ - #110#116#32#111#102#102#115#101#116#32#48#32#119#114#105#116#101#100#101#102+ - #97#117#108#116#59#10#32#32#34#100#50#100#34#32#116#121#112#101#32#98#111+ - #111#108#32#111#102#102#115#101#116#32#56#32#100#101#102#97#117#108#116#32+ - #102#97#108#115#101#59#10#32#32#34#115#105#108#101#110#116#34#32#116#121#112+ - #101#32#98#111#111#108#32#111#102#102#115#101#116#32#57#32#100#101#102#97+ - #117#108#116#32#102#97#108#115#101#59#10#32#32#34#100#105#114#101#99#116#105+ - #111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#49#48#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100#101#102+ - #97#117#108#116#32#68#73#82#95#76#69#70#84#59#10#125#10#10#84#114#105#103+ - #103#101#114#68#97#116#97#32#102#111#114#32#40#84#82#73#71#71#69#82#95#79#80+ - #69#78#68#79#79#82#44#32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79#82+ - #44#32#84#82#73#71#71#69#82#95#68#79#79#82#44#32#84#82#73#71#71#69#82#95#68+ - #79#79#82#53#44#32#84#82#73#71#71#69#82#95#67#76#79#83#69#84#82#65#80#44#32+ - #84#82#73#71#71#69#82#95#84#82#65#80#44#32#84#82#73#71#71#69#82#95#76#73#70+ - #84#85#80#44#32#84#82#73#71#71#69#82#95#76#73#70#84#68#79#87#78#44#32#84#82+ - #73#71#71#69#82#95#76#73#70#84#41#32#123#10#32#32#34#112#97#110#101#108#105+ - #100#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#48+ - #32#112#97#110#101#108#32#119#114#105#116#101#100#101#102#97#117#108#116#59+ - #10#32#32#34#115#105#108#101#110#116#34#32#116#121#112#101#32#98#111#111#108+ - #32#111#102#102#115#101#116#32#52#32#100#101#102#97#117#108#116#32#102#97+ - #108#115#101#59#10#32#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111+ - #108#32#111#102#102#115#101#116#32#53#32#100#101#102#97#117#108#116#32#102+ - #97#108#115#101#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32+ - #102#111#114#32#40#84#82#73#71#71#69#82#95#80#82#69#83#83#44#32#84#82#73#71+ - #71#69#82#95#79#78#44#32#84#82#73#71#71#69#82#95#79#70#70#44#32#84#82#73#71+ - #71#69#82#95#79#78#79#70#70#41#32#123#10#32#32#34#112#111#115#105#116#105+ - #111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115#101+ - #116#32#48#32#97#115#32#116#120#121#32#100#101#102#97#117#108#116#32#40#48+ - #32#48#41#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34+ - #115#105#122#101#34#32#116#121#112#101#32#115#105#122#101#32#111#102#102#115+ - #101#116#32#56#32#97#115#32#116#119#104#32#100#101#102#97#117#108#116#32#40+ - #48#32#48#41#59#10#32#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115+ - #104#111#114#116#32#111#102#102#115#101#116#32#49#50#32#100#101#102#97#117+ - #108#116#32#48#59#10#32#32#34#99#111#117#110#116#34#32#97#108#105#97#115#32+ - #112#114#101#115#115#67#111#117#110#116#32#116#121#112#101#32#117#115#104+ - #111#114#116#32#111#102#102#115#101#116#32#49#52#32#100#101#102#97#117#108+ - #116#32#48#59#10#32#32#34#109#111#110#115#116#101#114#105#100#34#32#116#121+ - #112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#54#32#109#111#110+ - #115#116#101#114#32#97#115#32#109#111#110#115#116#101#114#105#100#32#100#101+ - #102#97#117#108#116#32#110#117#108#108#59#10#32#32#34#101#120#116#95#114#97+ - #110#100#111#109#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115+ - #101#116#32#50#48#32#100#101#102#97#117#108#116#32#102#97#108#115#101#59#10+ - #32#32#47#47#32#116#104#105#115#32#111#110#101#32#105#115#32#102#111#114#32+ - #109#111#118#105#110#103#32#112#108#97#116#102#111#114#109#115#10#32#32#34+ - #112#97#110#101#108#105#100#34#32#112#97#110#101#108#32#100#101#102#97#117+ - #108#116#32#110#117#108#108#59#10#32#32#34#115#105#108#101#110#116#34#32#116+ - #121#112#101#32#98#111#111#108#32#100#101#102#97#117#108#116#32#116#114#117+ - #101#59#10#32#32#34#115#111#117#110#100#34#32#116#121#112#101#32#115#116#114+ - #105#110#103#32#100#101#102#97#117#108#116#32#34#34#59#10#125#10#10#101#110+ - #117#109#32#84#114#105#103#103#101#114#83#99#111#114#101#84#101#97#109#32+ - #123#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#84#69#65#77#95#77#73+ - #78#69#95#82#69#68#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#67+ - #79#82#69#95#84#69#65#77#95#77#73#78#69#95#66#76#85#69#44#32#47#47#32#49#10+ - #32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#84#69#65#77#95#70#79#82#67+ - #69#95#82#69#68#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#67#79+ - #82#69#95#84#69#65#77#95#70#79#82#67#69#95#66#76#85#69#44#32#47#47#32#51#10+ - #125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82+ - #73#71#71#69#82#95#83#69#67#82#69#84#32#123#10#125#10#10#84#114#105#103#103+ - #101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#88#84+ - #85#82#69#32#123#10#32#32#34#97#99#116#105#118#97#116#101#95#111#110#99#101+ - #34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#48#32+ - #100#101#102#97#117#108#116#32#102#97#108#115#101#32#119#114#105#116#101#100+ - #101#102#97#117#108#116#59#10#32#32#34#97#110#105#109#97#116#101#95#111#110+ - #99#101#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116+ - #32#49#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32#119#114#105+ - #116#101#100#101#102#97#117#108#116#59#10#125#10#10#84#114#105#103#103#101+ - #114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#79#85#78#68+ - #32#123#10#32#32#34#115#111#117#110#100#95#110#97#109#101#34#32#116#121#112+ - #101#32#99#104#97#114#91#54#52#93#32#111#102#102#115#101#116#32#48#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#118#111#108#117+ - #109#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#54#52#32#100#101#102#97#117#108#116#32#48#32#119#114#105#116#101#100+ - #101#102#97#117#108#116#59#32#47#47#63#63#63#32#100#101#102#97#117#108#116+ - #32#63#63#63#10#32#32#34#112#97#110#34#32#116#121#112#101#32#117#98#121#116+ - #101#32#111#102#102#115#101#116#32#54#53#32#100#101#102#97#117#108#116#32#48+ - #59#10#32#32#34#108#111#99#97#108#34#32#116#121#112#101#32#98#111#111#108#32+ - #111#102#102#115#101#116#32#54#54#32#100#101#102#97#117#108#116#32#116#114+ - #117#101#59#32#47#47#63#63#63#32#100#101#102#97#117#108#116#32#63#63#63#10+ - #32#32#34#112#108#97#121#95#99#111#117#110#116#34#32#116#121#112#101#32#117+ - #98#121#116#101#32#111#102#102#115#101#116#32#54#55#32#100#101#102#97#117+ - #108#116#32#49#59#10#32#32#34#115#111#117#110#100#95#115#119#105#116#99#104+ - #34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#56+ - #32#100#101#102#97#117#108#116#32#102#97#108#115#101#59#32#47#47#63#63#63#32+ - #100#101#102#97#117#108#116#32#63#63#63#10#125#10#10#84#114#105#103#103#101+ - #114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78+ - #77#79#78#83#84#69#82#32#123#10#32#32#34#112#111#115#105#116#105#111#110#34+ - #32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48+ - #32#97#115#32#116#120#121#32#119#114#105#116#101#100#101#102#97#117#108#116+ - #59#10#32#32#34#116#121#112#101#34#32#97#108#105#97#115#32#115#112#97#119+ - #110#77#111#110#115#84#121#112#101#32#116#121#112#101#32#117#98#121#116#101+ - #32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#77#111#110#115#116+ - #101#114#32#100#101#102#97#117#108#116#32#77#79#78#83#84#69#82#95#73#77#80+ - #32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#104#101#97+ - #108#116#104#34#32#116#121#112#101#32#105#110#116#32#111#102#102#115#101#116+ - #32#49#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34+ - #100#105#114#101#99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116+ - #101#32#111#102#102#115#101#116#32#49#54#32#101#110#117#109#32#68#105#114#84+ - #121#112#101#32#100#101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#97#99#116#105#118+ - #101#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32+ - #49#55#32#100#101#102#97#117#108#116#32#116#114#117#101#59#10#32#32#34#99+ - #111#117#110#116#34#32#97#108#105#97#115#32#109#111#110#115#67#111#117#110+ - #116#32#116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#50#48+ - #32#100#101#102#97#117#108#116#32#49#32#119#114#105#116#101#100#101#102#97+ - #117#108#116#59#10#32#32#34#101#102#102#101#99#116#34#32#116#121#112#101#32+ - #117#98#121#116#101#32#111#102#102#115#101#116#32#50#52#32#101#110#117#109+ - #32#69#102#102#101#99#116#65#99#116#105#111#110#32#100#101#102#97#117#108+ - #116#32#69#70#70#69#67#84#95#78#79#78#69#32#119#114#105#116#101#100#101#102+ - #97#117#108#116#59#10#32#32#34#109#97#120#34#32#116#121#112#101#32#117#115+ - #104#111#114#116#32#111#102#102#115#101#116#32#50#54#32#100#101#102#97#117+ - #108#116#32#49#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32+ - #34#100#101#108#97#121#34#32#116#121#112#101#32#117#115#104#111#114#116#32+ - #111#102#102#115#101#116#32#50#56#32#100#101#102#97#117#108#116#32#49#48#48+ - #48#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#98#101+ - #104#97#118#105#111#117#114#34#32#116#121#112#101#32#117#98#121#116#101#32+ - #111#102#102#115#101#116#32#51#48#32#101#110#117#109#32#77#111#110#115#116+ - #101#114#66#101#104#97#118#105#111#117#114#32#100#101#102#97#117#108#116#32+ - #66#72#95#78#79#82#77#65#76#59#10#125#10#10#84#114#105#103#103#101#114#68#97+ - #116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84#69#77+ - #32#123#10#32#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101#32+ - #112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115#32#116#120+ - #121#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#116+ - #121#112#101#34#32#97#108#105#97#115#32#115#112#97#119#110#73#116#101#109#84+ - #121#112#101#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#56#32#101#110#117#109#32#73#116#101#109#32#100#101#102#97#117#108+ - #116#32#73#84#69#77#95#78#79#78#69#32#119#114#105#116#101#100#101#102#97#117+ - #108#116#59#10#32#32#34#103#114#97#118#105#116#121#34#32#116#121#112#101#32+ + #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47+ + #47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#47#10#47#47#32#118#97#114+ + #105#111#117#115#32#116#114#105#103#103#101#114#115#10#84#114#105#103#103+ + #101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#69#88#73#84+ + #32#123#10#32#32#34#109#97#112#34#32#116#121#112#101#32#99#104#97#114#91#49+ + #54#93#32#111#102#102#115#101#116#32#48#32#119#114#105#116#101#100#101#102+ + #97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32+ + #102#111#114#32#84#82#73#71#71#69#82#95#84#69#76#69#80#79#82#84#32#123#10#32+ + #32#34#116#97#114#103#101#116#34#32#116#121#112#101#32#112#111#105#110#116+ + #32#111#102#102#115#101#116#32#48#32#119#114#105#116#101#100#101#102#97#117+ + #108#116#59#10#32#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108+ + #32#111#102#102#115#101#116#32#56#32#100#101#102#97#117#108#116#32#102#97+ + #108#115#101#59#10#32#32#34#115#105#108#101#110#116#34#32#116#121#112#101#32+ #98#111#111#108#32#111#102#102#115#101#116#32#57#32#100#101#102#97#117#108+ - #116#32#116#114#117#101#59#10#32#32#34#100#109#111#110#108#121#34#32#116#121+ - #112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#48#32#100#101+ - #102#97#117#108#116#32#102#97#108#115#101#59#10#32#32#34#99#111#117#110#116+ - #34#32#97#108#105#97#115#32#105#116#101#109#67#111#117#110#116#32#116#121+ - #112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#32#100#101#102+ - #97#117#108#116#32#49#59#10#32#32#34#101#102#102#101#99#116#34#32#116#121+ - #112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#54#32#101+ - #110#117#109#32#69#102#102#101#99#116#65#99#116#105#111#110#32#100#101#102+ - #97#117#108#116#32#69#70#70#69#67#84#95#78#79#78#69#32#119#114#105#116#101+ - #100#101#102#97#117#108#116#59#10#32#32#34#109#97#120#34#32#116#121#112#101+ - #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#56#32#100#101+ - #102#97#117#108#116#32#49#59#10#32#32#34#100#101#108#97#121#34#32#116#121+ - #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#48#32+ - #100#101#102#97#117#108#116#32#49#48#48#48#32#119#114#105#116#101#100#101+ - #102#97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97+ - #32#102#111#114#32#84#82#73#71#71#69#82#95#77#85#83#73#67#32#123#10#32#32#34+ - #110#97#109#101#34#32#97#108#105#97#115#32#109#117#115#105#99#78#97#109#101+ - #32#116#121#112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115#101#116+ - #32#48#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#97+ - #99#116#105#111#110#34#32#97#108#105#97#115#32#109#117#115#105#99#65#99#116+ - #105#111#110#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#54#52#32#101#110#117#109#32#84#114#105#103#103#101#114#77#117#115+ - #105#99#65#99#116#105#111#110#32#119#114#105#116#101#100#101#102#97#117#108+ - #116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114+ - #32#84#82#73#71#71#69#82#95#80#85#83#72#32#123#10#32#32#34#97#110#103#108+ - #101#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+ - #116#32#48#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34+ - #102#111#114#99#101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102+ - #102#115#101#116#32#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59+ - #10#32#32#34#114#101#115#101#116#95#118#101#108#111#99#105#116#121#34#32#116+ - #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#51#32#100#101+ + #116#32#102#97#108#115#101#59#10#32#32#34#100#105#114#101#99#116#105#111#110+ + #34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32+ + #49#48#32#101#110#117#109#32#68#105#114#84#121#112#101#32#100#101#102#97#117+ + #108#116#32#68#73#82#95#76#69#70#84#59#10#125#10#10#84#114#105#103#103#101+ + #114#68#97#116#97#32#102#111#114#32#40#84#82#73#71#71#69#82#95#79#80#69#78+ + #68#79#79#82#44#32#84#82#73#71#71#69#82#95#67#76#79#83#69#68#79#79#82#44#32+ + #84#82#73#71#71#69#82#95#68#79#79#82#44#32#84#82#73#71#71#69#82#95#68#79#79+ + #82#53#44#32#84#82#73#71#71#69#82#95#67#76#79#83#69#84#82#65#80#44#32#84#82+ + #73#71#71#69#82#95#84#82#65#80#44#32#84#82#73#71#71#69#82#95#76#73#70#84#85+ + #80#44#32#84#82#73#71#71#69#82#95#76#73#70#84#68#79#87#78#44#32#84#82#73#71+ + #71#69#82#95#76#73#70#84#41#32#123#10#32#32#34#112#97#110#101#108#105#100#34+ + #32#116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#48#32#112+ + #97#110#101#108#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32+ + #32#34#115#105#108#101#110#116#34#32#116#121#112#101#32#98#111#111#108#32+ + #111#102#102#115#101#116#32#52#32#100#101#102#97#117#108#116#32#102#97#108+ + #115#101#59#10#32#32#34#100#50#100#34#32#116#121#112#101#32#98#111#111#108+ + #32#111#102#102#115#101#116#32#53#32#100#101#102#97#117#108#116#32#102#97+ + #108#115#101#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+ + #111#114#32#40#84#82#73#71#71#69#82#95#80#82#69#83#83#44#32#84#82#73#71#71+ + #69#82#95#79#78#44#32#84#82#73#71#71#69#82#95#79#70#70#44#32#84#82#73#71#71+ + #69#82#95#79#78#79#70#70#41#32#123#10#32#32#34#112#111#115#105#116#105#111+ + #110#34#32#116#121#112#101#32#112#111#105#110#116#32#111#102#102#115#101#116+ + #32#48#32#97#115#32#116#120#121#32#100#101#102#97#117#108#116#32#40#48#32#48+ + #41#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#105+ + #122#101#34#32#116#121#112#101#32#115#105#122#101#32#111#102#102#115#101#116+ + #32#56#32#97#115#32#116#119#104#32#100#101#102#97#117#108#116#32#40#48#32#48+ + #41#59#10#32#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115#104#111+ + #114#116#32#111#102#102#115#101#116#32#49#50#32#100#101#102#97#117#108#116+ + #32#48#59#10#32#32#34#99#111#117#110#116#34#32#97#108#105#97#115#32#112#114+ + #101#115#115#67#111#117#110#116#32#116#121#112#101#32#117#115#104#111#114+ + #116#32#111#102#102#115#101#116#32#49#52#32#100#101#102#97#117#108#116#32#48+ + #59#10#32#32#34#109#111#110#115#116#101#114#105#100#34#32#116#121#112#101#32+ + #105#110#116#32#111#102#102#115#101#116#32#49#54#32#109#111#110#115#116#101+ + #114#32#97#115#32#109#111#110#115#116#101#114#105#100#32#100#101#102#97#117+ + #108#116#32#110#117#108#108#59#10#32#32#34#101#120#116#95#114#97#110#100#111+ + #109#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32+ + #50#48#32#100#101#102#97#117#108#116#32#102#97#108#115#101#59#10#32#32#47#47+ + #32#116#104#105#115#32#111#110#101#32#105#115#32#102#111#114#32#109#111#118+ + #105#110#103#32#112#108#97#116#102#111#114#109#115#10#32#32#34#112#97#110+ + #101#108#105#100#34#32#112#97#110#101#108#32#100#101#102#97#117#108#116#32+ + #110#117#108#108#59#10#32#32#34#115#105#108#101#110#116#34#32#116#121#112+ + #101#32#98#111#111#108#32#100#101#102#97#117#108#116#32#116#114#117#101#59+ + #10#32#32#34#115#111#117#110#100#34#32#116#121#112#101#32#115#116#114#105+ + #110#103#32#100#101#102#97#117#108#116#32#34#34#59#10#125#10#10#101#110#117+ + #109#32#84#114#105#103#103#101#114#83#99#111#114#101#84#101#97#109#32#123#10+ + #32#32#84#82#73#71#71#69#82#95#83#67#79#82#69#95#84#69#65#77#95#77#73#78#69+ + #95#82#69#68#44#32#47#47#32#48#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82+ + #69#95#84#69#65#77#95#77#73#78#69#95#66#76#85#69#44#32#47#47#32#49#10#32#32+ + #84#82#73#71#71#69#82#95#83#67#79#82#69#95#84#69#65#77#95#70#79#82#67#69#95+ + #82#69#68#44#32#47#47#32#50#10#32#32#84#82#73#71#71#69#82#95#83#67#79#82#69+ + #95#84#69#65#77#95#70#79#82#67#69#95#66#76#85#69#44#32#47#47#32#51#10#125#10+ + #10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71#71+ + #69#82#95#83#69#67#82#69#84#32#123#10#125#10#10#84#114#105#103#103#101#114+ + #68#97#116#97#32#102#111#114#32#84#82#73#71#71#69#82#95#84#69#88#84#85#82#69+ + #32#123#10#32#32#34#97#99#116#105#118#97#116#101#95#111#110#99#101#34#32#116+ + #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#48#32#100#101+ #102#97#117#108#116#32#102#97#108#115#101#32#119#114#105#116#101#100#101#102+ - #97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32+ - #102#111#114#32#84#82#73#71#71#69#82#95#83#67#79#82#69#32#123#10#32#32#34#97+ - #99#116#105#111#110#34#32#97#108#105#97#115#32#115#99#111#114#101#65#99#116+ - #105#111#110#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#48#32#101#110#117#109#32#84#114#105#103#103#101#114#83#99#111#114+ - #101#65#99#116#105#111#110#32#100#101#102#97#117#108#116#32#84#82#73#71#71+ - #69#82#95#83#67#79#82#69#95#65#67#84#73#79#78#95#65#68#68#32#119#114#105#116+ - #101#100#101#102#97#117#108#116#59#10#32#32#34#99#111#117#110#116#34#32#97+ - #108#105#97#115#32#115#99#111#114#101#67#111#117#110#116#32#116#121#112#101+ - #32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#32#100#101#102#97+ - #117#108#116#32#49#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10+ - #32#32#34#116#101#97#109#34#32#97#108#105#97#115#32#115#99#111#114#101#84+ - #101#97#109#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#50#32#101#110#117#109#32#84#114#105#103#103#101#114#83#99#111#114+ - #101#84#101#97#109#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10+ - #32#32#34#99#111#110#115#111#108#101#34#32#97#108#105#97#115#32#115#99#111+ - #114#101#67#111#110#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115+ - #101#116#32#51#32#100#101#102#97#117#108#116#32#102#97#108#115#101#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#109#101#115#115+ - #97#103#101#34#32#97#108#105#97#115#32#115#99#111#114#101#77#115#103#32#116+ - #121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#52#32#100#101+ - #102#97#117#108#116#32#116#114#117#101#32#119#114#105#116#101#100#101#102#97+ - #117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+ - #111#114#32#84#82#73#71#71#69#82#95#77#69#83#83#65#71#69#32#123#10#32#32#34+ - #107#105#110#100#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+ - #115#101#116#32#48#32#101#110#117#109#32#84#114#105#103#103#101#114#77#101+ - #115#115#97#103#101#75#105#110#100#32#100#101#102#97#117#108#116#32#84#82#73+ - #71#71#69#82#95#77#69#83#83#65#71#69#95#75#73#78#68#95#71#65#77#69#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#100#101#115#116+ - #34#32#97#108#105#97#115#32#109#115#103#68#101#115#116#32#116#121#112#101#32+ - #117#98#121#116#101#32#101#110#117#109#32#84#114#105#103#103#101#114#77#101+ - #115#115#97#103#101#68#101#115#116#32#111#102#102#115#101#116#32#49#59#10#32+ - #32#34#116#101#120#116#34#32#116#121#112#101#32#99#104#97#114#91#49#48#48#93+ - #32#111#102#102#115#101#116#32#50#32#119#114#105#116#101#100#101#102#97#117+ - #108#116#59#10#32#32#34#116#105#109#101#34#32#97#108#105#97#115#32#109#115+ - #103#84#105#109#101#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102+ - #102#115#101#116#32#49#48#50#32#119#114#105#116#101#100#101#102#97#117#108+ - #116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114+ - #32#84#82#73#71#71#69#82#95#68#65#77#65#71#69#32#123#10#32#32#34#97#109#111+ - #117#110#116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102+ - #115#101#116#32#48#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10+ - #32#32#34#105#110#116#101#114#118#97#108#34#32#116#121#112#101#32#117#115+ - #104#111#114#116#32#111#102#102#115#101#116#32#50#32#119#114#105#116#101#100+ - #101#102#97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116+ - #97#32#102#111#114#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#32#123#10#32+ - #32#34#97#109#111#117#110#116#34#32#116#121#112#101#32#117#115#104#111#114+ - #116#32#111#102#102#115#101#116#32#48#32#119#114#105#116#101#100#101#102#97+ - #117#108#116#59#10#32#32#34#105#110#116#101#114#118#97#108#34#32#116#121#112+ - #101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#32#119#114+ - #105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#109#97#120#34#32#97+ - #108#105#97#115#32#104#101#97#108#77#97#120#32#116#121#112#101#32#98#111#111+ - #108#32#111#102#102#115#101#116#32#52#32#119#114#105#116#101#100#101#102#97+ - #117#108#116#59#10#32#32#34#115#105#108#101#110#116#34#32#116#121#112#101#32+ - #98#111#111#108#32#111#102#102#115#101#116#32#53#32#119#114#105#116#101#100+ + #97#117#108#116#59#10#32#32#34#97#110#105#109#97#116#101#95#111#110#99#101+ + #34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#32+ + #100#101#102#97#117#108#116#32#102#97#108#115#101#32#119#114#105#116#101#100+ #101#102#97#117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116+ - #97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#72#79#84#32#123#10#32#32#34+ - #112#111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110+ - #116#32#111#102#102#115#101#116#32#48#32#97#115#32#116#120#121#32#119#114+ - #105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#116#121#112#101#34#32+ - #97#108#105#97#115#32#115#104#111#116#84#121#112#101#32#116#121#112#101#32+ - #117#98#121#116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32+ - #84#114#105#103#103#101#114#83#104#111#116#32#119#114#105#116#101#100#101+ - #102#97#117#108#116#59#10#32#32#34#116#97#114#103#101#116#34#32#97#108#105+ - #97#115#32#115#104#111#116#84#97#114#103#101#116#32#116#121#112#101#32#117+ - #98#121#116#101#32#111#102#102#115#101#116#32#57#32#101#110#117#109#32#84+ - #114#105#103#103#101#114#83#104#111#116#84#97#114#103#101#116#32#119#114#105+ - #116#101#100#101#102#97#117#108#116#59#10#32#32#34#113#117#105#101#116#34#32+ - #116#121#112#101#32#110#101#103#98#111#111#108#32#111#102#102#115#101#116#32+ - #49#48#59#32#47#47#32#110#101#103#98#111#111#108#33#10#32#32#34#97#105#109+ - #34#32#116#121#112#101#32#98#121#116#101#32#111#102#102#115#101#116#32#49#49+ - #32#101#110#117#109#32#84#114#105#103#103#101#114#83#104#111#116#65#105#109+ - #32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65+ - #73#77#95#68#69#70#65#85#76#84#59#10#32#32#34#112#97#110#101#108#105#100#34+ + #97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#79#85#78#68#32#123#10#32#32+ + #34#115#111#117#110#100#95#110#97#109#101#34#32#116#121#112#101#32#99#104#97+ + #114#91#54#52#93#32#111#102#102#115#101#116#32#48#32#119#114#105#116#101#100+ + #101#102#97#117#108#116#59#10#32#32#34#118#111#108#117#109#101#34#32#116#121+ + #112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#54#52#32#100+ + #101#102#97#117#108#116#32#48#32#119#114#105#116#101#100#101#102#97#117#108+ + #116#59#32#47#47#63#63#63#32#100#101#102#97#117#108#116#32#63#63#63#10#32#32+ + #34#112#97#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+ + #115#101#116#32#54#53#32#100#101#102#97#117#108#116#32#48#59#10#32#32#34#108+ + #111#99#97#108#34#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115+ + #101#116#32#54#54#32#100#101#102#97#117#108#116#32#116#114#117#101#59#32#47+ + #47#63#63#63#32#100#101#102#97#117#108#116#32#63#63#63#10#32#32#34#112#108+ + #97#121#95#99#111#117#110#116#34#32#116#121#112#101#32#117#98#121#116#101#32+ + #111#102#102#115#101#116#32#54#55#32#100#101#102#97#117#108#116#32#49#59#10+ + #32#32#34#115#111#117#110#100#95#115#119#105#116#99#104#34#32#116#121#112+ + #101#32#98#111#111#108#32#111#102#102#115#101#116#32#54#56#32#100#101#102#97+ + #117#108#116#32#102#97#108#115#101#59#32#47#47#63#63#63#32#100#101#102#97+ + #117#108#116#32#63#63#63#10#125#10#10#84#114#105#103#103#101#114#68#97#116+ + #97#32#102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78#77#79#78#83#84+ + #69#82#32#123#10#32#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112+ + #101#32#112#111#105#110#116#32#111#102#102#115#101#116#32#48#32#97#115#32+ + #116#120#121#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32+ + #34#116#121#112#101#34#32#97#108#105#97#115#32#115#112#97#119#110#77#111#110+ + #115#84#121#112#101#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+ + #115#101#116#32#56#32#101#110#117#109#32#77#111#110#115#116#101#114#32#100+ + #101#102#97#117#108#116#32#77#79#78#83#84#69#82#95#73#77#80#32#119#114#105+ + #116#101#100#101#102#97#117#108#116#59#10#32#32#34#104#101#97#108#116#104#34+ #32#116#121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#32+ - #112#97#110#101#108#32#100#101#102#97#117#108#116#32#110#117#108#108#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#105#103#104+ + #119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#100#105#114+ + #101#99#116#105#111#110#34#32#116#121#112#101#32#117#98#121#116#101#32#111+ + #102#102#115#101#116#32#49#54#32#101#110#117#109#32#68#105#114#84#121#112+ + #101#32#100#101#102#97#117#108#116#32#68#73#82#95#76#69#70#84#32#119#114#105+ + #116#101#100#101#102#97#117#108#116#59#10#32#32#34#97#99#116#105#118#101#34+ + #32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#55#32+ + #100#101#102#97#117#108#116#32#116#114#117#101#59#10#32#32#34#99#111#117#110+ + #116#34#32#97#108#105#97#115#32#109#111#110#115#67#111#117#110#116#32#116+ + #121#112#101#32#105#110#116#32#111#102#102#115#101#116#32#50#48#32#100#101+ + #102#97#117#108#116#32#49#32#119#114#105#116#101#100#101#102#97#117#108#116+ + #59#10#32#32#34#101#102#102#101#99#116#34#32#116#121#112#101#32#117#98#121+ + #116#101#32#111#102#102#115#101#116#32#50#52#32#101#110#117#109#32#69#102+ + #102#101#99#116#65#99#116#105#111#110#32#100#101#102#97#117#108#116#32#69#70+ + #70#69#67#84#95#78#79#78#69#32#119#114#105#116#101#100#101#102#97#117#108+ + #116#59#10#32#32#34#109#97#120#34#32#116#121#112#101#32#117#115#104#111#114+ + #116#32#111#102#102#115#101#116#32#50#54#32#100#101#102#97#117#108#116#32#49+ + #32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#100#101+ + #108#97#121#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102+ + #115#101#116#32#50#56#32#100#101#102#97#117#108#116#32#49#48#48#48#32#119+ + #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#98#101#104#97#118+ + #105#111#117#114#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+ + #115#101#116#32#51#48#32#101#110#117#109#32#77#111#110#115#116#101#114#66+ + #101#104#97#118#105#111#117#114#32#100#101#102#97#117#108#116#32#66#72#95#78+ + #79#82#77#65#76#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32+ + #102#111#114#32#84#82#73#71#71#69#82#95#83#80#65#87#78#73#84#69#77#32#123#10+ + #32#32#34#112#111#115#105#116#105#111#110#34#32#116#121#112#101#32#112#111+ + #105#110#116#32#111#102#102#115#101#116#32#48#32#97#115#32#116#120#121#32+ + #119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#116#121#112+ + #101#34#32#97#108#105#97#115#32#115#112#97#119#110#73#116#101#109#84#121#112+ + #101#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32+ + #56#32#101#110#117#109#32#73#116#101#109#32#100#101#102#97#117#108#116#32#73+ + #84#69#77#95#78#79#78#69#32#119#114#105#116#101#100#101#102#97#117#108#116+ + #59#10#32#32#34#103#114#97#118#105#116#121#34#32#116#121#112#101#32#98#111+ + #111#108#32#111#102#102#115#101#116#32#57#32#100#101#102#97#117#108#116#32+ + #116#114#117#101#59#10#32#32#34#100#109#111#110#108#121#34#32#116#121#112+ + #101#32#98#111#111#108#32#111#102#102#115#101#116#32#49#48#32#100#101#102#97+ + #117#108#116#32#102#97#108#115#101#59#10#32#32#34#99#111#117#110#116#34#32+ + #97#108#105#97#115#32#105#116#101#109#67#111#117#110#116#32#116#121#112#101+ + #32#105#110#116#32#111#102#102#115#101#116#32#49#50#32#100#101#102#97#117+ + #108#116#32#49#59#10#32#32#34#101#102#102#101#99#116#34#32#116#121#112#101+ + #32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#54#32#101#110#117+ + #109#32#69#102#102#101#99#116#65#99#116#105#111#110#32#100#101#102#97#117+ + #108#116#32#69#70#70#69#67#84#95#78#79#78#69#32#119#114#105#116#101#100#101+ + #102#97#117#108#116#59#10#32#32#34#109#97#120#34#32#116#121#112#101#32#117+ + #115#104#111#114#116#32#111#102#102#115#101#116#32#49#56#32#100#101#102#97+ + #117#108#116#32#49#59#10#32#32#34#100#101#108#97#121#34#32#116#121#112#101+ + #32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#48#32#100#101+ + #102#97#117#108#116#32#49#48#48#48#32#119#114#105#116#101#100#101#102#97#117+ + #108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111+ + #114#32#84#82#73#71#71#69#82#95#77#85#83#73#67#32#123#10#32#32#34#110#97#109+ + #101#34#32#97#108#105#97#115#32#109#117#115#105#99#78#97#109#101#32#116#121+ + #112#101#32#99#104#97#114#91#54#52#93#32#111#102#102#115#101#116#32#48#32+ + #119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#97#99#116#105+ + #111#110#34#32#97#108#105#97#115#32#109#117#115#105#99#65#99#116#105#111#110+ + #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#54+ + #52#32#101#110#117#109#32#84#114#105#103#103#101#114#77#117#115#105#99#65#99+ + #116#105#111#110#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#125+ + #10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82#73#71+ + #71#69#82#95#80#85#83#72#32#123#10#32#32#34#97#110#103#108#101#34#32#116#121+ + #112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#48#32#119+ + #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#102#111#114#99+ + #101#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116+ + #32#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#114+ + #101#115#101#116#95#118#101#108#111#99#105#116#121#34#32#116#121#112#101#32+ + #98#111#111#108#32#111#102#102#115#101#116#32#51#32#100#101#102#97#117#108+ + #116#32#102#97#108#115#101#32#119#114#105#116#101#100#101#102#97#117#108#116+ + #59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32+ + #84#82#73#71#71#69#82#95#83#67#79#82#69#32#123#10#32#32#34#97#99#116#105#111+ + #110#34#32#97#108#105#97#115#32#115#99#111#114#101#65#99#116#105#111#110#32+ + #116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#48#32+ + #101#110#117#109#32#84#114#105#103#103#101#114#83#99#111#114#101#65#99#116+ + #105#111#110#32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95#83#67+ + #79#82#69#95#65#67#84#73#79#78#95#65#68#68#32#119#114#105#116#101#100#101+ + #102#97#117#108#116#59#10#32#32#34#99#111#117#110#116#34#32#97#108#105#97+ + #115#32#115#99#111#114#101#67#111#117#110#116#32#116#121#112#101#32#117#98+ + #121#116#101#32#111#102#102#115#101#116#32#49#32#100#101#102#97#117#108#116+ + #32#49#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#116+ + #101#97#109#34#32#97#108#105#97#115#32#115#99#111#114#101#84#101#97#109#32+ + #116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#50#32+ + #101#110#117#109#32#84#114#105#103#103#101#114#83#99#111#114#101#84#101#97+ + #109#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#99#111+ + #110#115#111#108#101#34#32#97#108#105#97#115#32#115#99#111#114#101#67#111+ + #110#32#116#121#112#101#32#98#111#111#108#32#111#102#102#115#101#116#32#51+ + #32#100#101#102#97#117#108#116#32#102#97#108#115#101#32#119#114#105#116#101+ + #100#101#102#97#117#108#116#59#10#32#32#34#109#101#115#115#97#103#101#34#32+ + #97#108#105#97#115#32#115#99#111#114#101#77#115#103#32#116#121#112#101#32#98+ + #111#111#108#32#111#102#102#115#101#116#32#52#32#100#101#102#97#117#108#116+ + #32#116#114#117#101#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10+ + #125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82+ + #73#71#71#69#82#95#77#69#83#83#65#71#69#32#123#10#32#32#34#107#105#110#100+ + #34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32+ + #48#32#101#110#117#109#32#84#114#105#103#103#101#114#77#101#115#115#97#103+ + #101#75#105#110#100#32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95+ + #77#69#83#83#65#71#69#95#75#73#78#68#95#71#65#77#69#32#119#114#105#116#101+ + #100#101#102#97#117#108#116#59#10#32#32#34#100#101#115#116#34#32#97#108#105+ + #97#115#32#109#115#103#68#101#115#116#32#116#121#112#101#32#117#98#121#116+ + #101#32#101#110#117#109#32#84#114#105#103#103#101#114#77#101#115#115#97#103+ + #101#68#101#115#116#32#111#102#102#115#101#116#32#49#59#10#32#32#34#116#101+ + #120#116#34#32#116#121#112#101#32#99#104#97#114#91#49#48#48#93#32#111#102+ + #102#115#101#116#32#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59+ + #10#32#32#34#116#105#109#101#34#32#97#108#105#97#115#32#109#115#103#84#105+ + #109#101#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115+ + #101#116#32#49#48#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10+ + #125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32#84#82+ + #73#71#71#69#82#95#68#65#77#65#71#69#32#123#10#32#32#34#97#109#111#117#110+ #116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+ - #116#32#49#54#59#10#32#32#34#97#110#103#108#101#34#32#116#121#112#101#32#117+ - #115#104#111#114#116#32#111#102#102#115#101#116#32#49#56#59#10#32#32#34#119+ - #97#105#116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102+ - #115#101#116#32#50#48#59#10#32#32#34#97#99#99#117#114#97#99#121#34#32#116+ - #121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#50+ - #59#10#32#32#34#97#109#109#111#34#32#116#121#112#101#32#117#115#104#111#114+ - #116#32#111#102#102#115#101#116#32#50#52#59#10#32#32#34#114#101#108#111#97+ - #100#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101+ - #116#32#50#54#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+ - #111#114#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#32#123#10#32#32#34#99+ - #111#117#110#116#34#32#97#108#105#97#115#32#70#88#67#111#117#110#116#32#116+ - #121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#48#32#119+ - #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#116#121#112#101+ - #34#32#97#108#105#97#115#32#70#88#84#121#112#101#32#116#121#112#101#32#117+ - #98#121#116#101#32#111#102#102#115#101#116#32#49#32#101#110#117#109#32#84+ - #114#105#103#103#101#114#69#102#102#101#99#116#32#100#101#102#97#117#108#116+ - #32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#80#65#82#84#73#67#76#69#32+ - #119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#117#98+ - #116#121#112#101#34#32#97#108#105#97#115#32#70#88#83#117#98#84#121#112#101+ - #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#50+ - #32#101#110#117#109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#84+ - #121#112#101#32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95#69#70+ - #70#69#67#84#95#83#80#65#82#75#32#119#114#105#116#101#100#101#102#97#117#108+ - #116#59#10#32#32#34#114#101#100#34#32#97#108#105#97#115#32#70#88#82#101#100+ - #32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#51+ - #32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#103#114+ - #101#101#110#34#32#97#108#105#97#115#32#70#88#71#114#101#101#110#32#116#121+ - #112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#52#32#119#114+ - #105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#98#108#117#101#34#32+ - #97#108#105#97#115#32#70#88#66#108#117#101#32#116#121#112#101#32#117#98#121+ - #116#101#32#111#102#102#115#101#116#32#53#32#119#114#105#116#101#100#101#102+ - #97#117#108#116#59#10#32#32#34#112#111#115#34#32#97#108#105#97#115#32#70#88+ - #80#111#115#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101+ - #116#32#54#32#101#110#117#109#32#84#114#105#103#103#101#114#69#102#102#101+ - #99#116#80#111#115#32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95+ - #69#70#70#69#67#84#95#80#79#83#95#67#69#78#84#69#82#32#119#114#105#116#101+ - #100#101#102#97#117#108#116#59#10#32#32#34#119#97#105#116#34#32#116#121#112+ - #101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#56#32#119#114+ - #105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#118#101#108#95#120#34+ - #32#116#121#112#101#32#98#121#116#101#32#111#102#102#115#101#116#32#49#48#32+ - #119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#118#101#108+ - #95#121#34#32#116#121#112#101#32#98#121#116#101#32#111#102#102#115#101#116+ - #32#49#49#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34+ - #115#112#114#101#97#100#95#108#34#32#116#121#112#101#32#117#98#121#116#101+ - #32#111#102#102#115#101#116#32#49#50#32#119#114#105#116#101#100#101#102#97+ - #117#108#116#59#10#32#32#34#115#112#114#101#97#100#95#114#34#32#116#121#112+ - #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#51#32#119#114+ - #105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#112#114#101#97+ - #100#95#117#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102#115+ - #101#116#32#49#52#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32+ - #32#34#115#112#114#101#97#100#95#100#34#32#116#121#112#101#32#117#98#121#116+ - #101#32#111#102#102#115#101#116#32#49#53#32#119#114#105#116#101#100#101#102+ - #97#117#108#116#59#10#125#10 + #116#32#48#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34+ + #105#110#116#101#114#118#97#108#34#32#116#121#112#101#32#117#115#104#111#114+ + #116#32#111#102#102#115#101#116#32#50#32#119#114#105#116#101#100#101#102#97+ + #117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+ + #111#114#32#84#82#73#71#71#69#82#95#72#69#65#76#84#72#32#123#10#32#32#34#97+ + #109#111#117#110#116#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111+ + #102#102#115#101#116#32#48#32#119#114#105#116#101#100#101#102#97#117#108#116+ + #59#10#32#32#34#105#110#116#101#114#118#97#108#34#32#116#121#112#101#32#117+ + #115#104#111#114#116#32#111#102#102#115#101#116#32#50#32#119#114#105#116#101+ + #100#101#102#97#117#108#116#59#10#32#32#34#109#97#120#34#32#97#108#105#97+ + #115#32#104#101#97#108#77#97#120#32#116#121#112#101#32#98#111#111#108#32#111+ + #102#102#115#101#116#32#52#32#119#114#105#116#101#100#101#102#97#117#108#116+ + #59#10#32#32#34#115#105#108#101#110#116#34#32#116#121#112#101#32#98#111#111+ + #108#32#111#102#102#115#101#116#32#53#32#119#114#105#116#101#100#101#102#97+ + #117#108#116#59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102+ + #111#114#32#84#82#73#71#71#69#82#95#83#72#79#84#32#123#10#32#32#34#112#111+ + #115#105#116#105#111#110#34#32#116#121#112#101#32#112#111#105#110#116#32#111+ + #102#102#115#101#116#32#48#32#97#115#32#116#120#121#32#119#114#105#116#101+ + #100#101#102#97#117#108#116#59#10#32#32#34#116#121#112#101#34#32#97#108#105+ + #97#115#32#115#104#111#116#84#121#112#101#32#116#121#112#101#32#117#98#121+ + #116#101#32#111#102#102#115#101#116#32#56#32#101#110#117#109#32#84#114#105+ + #103#103#101#114#83#104#111#116#32#119#114#105#116#101#100#101#102#97#117+ + #108#116#59#10#32#32#34#116#97#114#103#101#116#34#32#97#108#105#97#115#32+ + #115#104#111#116#84#97#114#103#101#116#32#116#121#112#101#32#117#98#121#116+ + #101#32#111#102#102#115#101#116#32#57#32#101#110#117#109#32#84#114#105#103+ + #103#101#114#83#104#111#116#84#97#114#103#101#116#32#119#114#105#116#101#100+ + #101#102#97#117#108#116#59#10#32#32#34#113#117#105#101#116#34#32#116#121#112+ + #101#32#110#101#103#98#111#111#108#32#111#102#102#115#101#116#32#49#48#59#32+ + #47#47#32#110#101#103#98#111#111#108#33#10#32#32#34#97#105#109#34#32#116#121+ + #112#101#32#98#121#116#101#32#111#102#102#115#101#116#32#49#49#32#101#110+ + #117#109#32#84#114#105#103#103#101#114#83#104#111#116#65#105#109#32#100#101+ + #102#97#117#108#116#32#84#82#73#71#71#69#82#95#83#72#79#84#95#65#73#77#95#68+ + #69#70#65#85#76#84#59#10#32#32#34#112#97#110#101#108#105#100#34#32#116#121+ + #112#101#32#105#110#116#32#111#102#102#115#101#116#32#49#50#32#112#97#110+ + #101#108#32#100#101#102#97#117#108#116#32#110#117#108#108#32#119#114#105#116+ + #101#100#101#102#97#117#108#116#59#10#32#32#34#115#105#103#104#116#34#32#116+ + #121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#49#54+ + #59#10#32#32#34#97#110#103#108#101#34#32#116#121#112#101#32#117#115#104#111+ + #114#116#32#111#102#102#115#101#116#32#49#56#59#10#32#32#34#119#97#105#116+ + #34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116+ + #32#50#48#59#10#32#32#34#97#99#99#117#114#97#99#121#34#32#116#121#112#101#32+ + #117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#50#59#10#32#32#34+ + #97#109#109#111#34#32#116#121#112#101#32#117#115#104#111#114#116#32#111#102+ + #102#115#101#116#32#50#52#59#10#32#32#34#114#101#108#111#97#100#34#32#116+ + #121#112#101#32#117#115#104#111#114#116#32#111#102#102#115#101#116#32#50#54+ + #59#10#125#10#10#84#114#105#103#103#101#114#68#97#116#97#32#102#111#114#32+ + #84#82#73#71#71#69#82#95#69#70#70#69#67#84#32#123#10#32#32#34#99#111#117#110+ + #116#34#32#97#108#105#97#115#32#70#88#67#111#117#110#116#32#116#121#112#101+ + #32#117#98#121#116#101#32#111#102#102#115#101#116#32#48#32#119#114#105#116+ + #101#100#101#102#97#117#108#116#59#10#32#32#34#116#121#112#101#34#32#97#108+ + #105#97#115#32#70#88#84#121#112#101#32#116#121#112#101#32#117#98#121#116#101+ + #32#111#102#102#115#101#116#32#49#32#101#110#117#109#32#84#114#105#103#103+ + #101#114#69#102#102#101#99#116#32#100#101#102#97#117#108#116#32#84#82#73#71+ + #71#69#82#95#69#70#70#69#67#84#95#80#65#82#84#73#67#76#69#32#119#114#105#116+ + #101#100#101#102#97#117#108#116#59#10#32#32#34#115#117#98#116#121#112#101#34+ + #32#97#108#105#97#115#32#70#88#83#117#98#84#121#112#101#32#116#121#112#101+ + #32#117#98#121#116#101#32#111#102#102#115#101#116#32#50#32#101#110#117#109+ + #32#84#114#105#103#103#101#114#69#102#102#101#99#116#84#121#112#101#32#100+ + #101#102#97#117#108#116#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84#95#83+ + #80#65#82#75#32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32+ + #34#114#101#100#34#32#97#108#105#97#115#32#70#88#82#101#100#32#116#121#112+ + #101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#51#32#119#114#105+ + #116#101#100#101#102#97#117#108#116#59#10#32#32#34#103#114#101#101#110#34#32+ + #97#108#105#97#115#32#70#88#71#114#101#101#110#32#116#121#112#101#32#117#98+ + #121#116#101#32#111#102#102#115#101#116#32#52#32#119#114#105#116#101#100#101+ + #102#97#117#108#116#59#10#32#32#34#98#108#117#101#34#32#97#108#105#97#115#32+ + #70#88#66#108#117#101#32#116#121#112#101#32#117#98#121#116#101#32#111#102+ + #102#115#101#116#32#53#32#119#114#105#116#101#100#101#102#97#117#108#116#59+ + #10#32#32#34#112#111#115#34#32#97#108#105#97#115#32#70#88#80#111#115#32#116+ + #121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#54#32#101+ + #110#117#109#32#84#114#105#103#103#101#114#69#102#102#101#99#116#80#111#115+ + #32#100#101#102#97#117#108#116#32#84#82#73#71#71#69#82#95#69#70#70#69#67#84+ + #95#80#79#83#95#67#69#78#84#69#82#32#119#114#105#116#101#100#101#102#97#117+ + #108#116#59#10#32#32#34#119#97#105#116#34#32#116#121#112#101#32#117#115#104+ + #111#114#116#32#111#102#102#115#101#116#32#56#32#119#114#105#116#101#100#101+ + #102#97#117#108#116#59#10#32#32#34#118#101#108#95#120#34#32#116#121#112#101+ + #32#98#121#116#101#32#111#102#102#115#101#116#32#49#48#32#119#114#105#116+ + #101#100#101#102#97#117#108#116#59#10#32#32#34#118#101#108#95#121#34#32#116+ + #121#112#101#32#98#121#116#101#32#111#102#102#115#101#116#32#49#49#32#119+ + #114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#112#114#101+ + #97#100#95#108#34#32#116#121#112#101#32#117#98#121#116#101#32#111#102#102+ + #115#101#116#32#49#50#32#119#114#105#116#101#100#101#102#97#117#108#116#59+ + #10#32#32#34#115#112#114#101#97#100#95#114#34#32#116#121#112#101#32#117#98+ + #121#116#101#32#111#102#102#115#101#116#32#49#51#32#119#114#105#116#101#100+ + #101#102#97#117#108#116#59#10#32#32#34#115#112#114#101#97#100#95#117#34#32+ + #116#121#112#101#32#117#98#121#116#101#32#111#102#102#115#101#116#32#49#52+ + #32#119#114#105#116#101#100#101#102#97#117#108#116#59#10#32#32#34#115#112+ + #114#101#97#100#95#100#34#32#116#121#112#101#32#117#98#121#116#101#32#111+ + #102#102#115#101#116#32#49#53#32#119#114#105#116#101#100#101#102#97#117#108+ + #116#59#10#125#10 ; \ No newline at end of file diff --git a/src/shared/xparser.pas b/src/shared/xparser.pas index f539536..bac4e4a 100644 --- a/src/shared/xparser.pas +++ b/src/shared/xparser.pas @@ -39,6 +39,13 @@ type TTBegin = 8; // left curly TTEnd = 9; // right curly TTDelim = 10; // other delimiters + // + TTLogAnd = 11; // && + TTLogOr = 12; // || + TTLessEqu = 13; // <= + TTGreatEqu = 14; // >= + TTNotEqu = 15; // != + TTEqu = 16; // == private mLine, mCol: Integer; @@ -67,6 +74,7 @@ type function skipBlanks (): Boolean; // ...and comments; returns `false` on eof function skipToken (): Boolean; // returns `false` on eof + //function skipToken1 (): Boolean; function expectId (): AnsiString; procedure expectId (const aid: AnsiString); @@ -83,6 +91,9 @@ type function expectDelim (const ch: AnsiChar): AnsiChar; function eatDelim (const ch: AnsiChar): Boolean; + public + property allowSignedNumbers: Boolean read mAllowSignedNumbers write mAllowSignedNumbers; + public property col: Integer read mCol; property line: Integer read mLine; @@ -336,6 +347,16 @@ begin end; +{ +function TTextParser.skipToken (): Boolean; +begin + writeln('getting token...'); + result := skipToken1(); + writeln(' got token: ', mTokType, ' <', mTokStr, '> : <', mTokChar, '>'); +end; +} + + function TTextParser.skipToken (): Boolean; procedure parseInt (); @@ -503,16 +524,27 @@ begin if (curChar = '_') or ((curChar >= 'A') and (curChar <= 'Z')) or ((curChar >= 'a') and (curChar <= 'z')) or (curChar >= #128) then begin parseId(); exit; end; // known delimiters? - case curChar of + mTokChar := curChar; + mTokType := TTDelim; + skipChar(); + if (curChar = '=') then + begin + case mTokChar of + '<': begin mTokType := TTLessEqu; mTokStr := '<='; skipChar(); exit; end; + '>': begin mTokType := TTGreatEqu; mTokStr := '>='; skipChar(); exit; end; + '!': begin mTokType := TTNotEqu; mTokStr := '!='; skipChar(); exit; end; + '=': begin mTokType := TTEqu; mTokStr := '=='; skipChar(); exit; end; + end; + end; + case mTokChar of ',': mTokType := TTComma; ':': mTokType := TTColon; ';': mTokType := TTSemi; '{': mTokType := TTBegin; '}': mTokType := TTEnd; - else mTokType := TTDelim; + '&': if (curChar = '&') then begin mTokType := TTLogAnd; mTokStr := '&&'; skipChar(); exit; end; + '|': if (curChar = '|') then begin mTokType := TTLogOr; mTokStr := '||'; skipChar(); exit; end; end; - mTokChar := curChar; - skipChar(); end; diff --git a/src/tools/mapgen.dpr b/src/tools/mapgen.dpr index 1a48505..28b035c 100644 --- a/src/tools/mapgen.dpr +++ b/src/tools/mapgen.dpr @@ -265,14 +265,21 @@ begin writeln('FATAL: mapdef not found!'); end; + writeln('parsing "mapdef.txt"...'); pr := TFileTextParser.Create(st, false); // don't own try dfmapdef := TDynMapDef.Create(pr); - except on e: Exception do - begin - writeln('ERROR at (', pr.tokLine, ',', pr.tokCol, '): ', e.message); - Halt(1); - end; + except + on e: TDynParseException do + begin + writeln('ERROR at (', e.tokLine, ',', e.tokCol, '): ', e.message); + Halt(1); + end; + on e: Exception do + begin + writeln('ERROR: ', e.message); + Halt(1); + end; end; pr.Free();