DIRECTORY SB, Basics, BasicTime, Convert, Buttons, Commander, CommandTool, Containers, IO, FileNames, FS, Labels, Menus, MessageWindow, Rope, VFonts, ViewerClasses, ViewerOps, ViewerTools; SBTool: CEDAR PROGRAM IMPORTS BasicTime, Buttons, Commander, CommandTool, Convert, Containers, IO, FileNames, FS, Labels, Menus, MessageWindow, Rope, SB, VFonts, ViewerOps, ViewerTools = BEGIN SBToolHandle: TYPE = REF SBToolRec; -- For data of a particular instance SBToolRec: TYPE = RECORD [ outer: Containers.Container _ NIL, height: CARDINAL _ 0, -- measured from top league: SB.League _ NIL, file: Rope.ROPE _ NIL, lVwr: LeagueViewers, team: SB.Team _ 0, tVwr: TeamViewersSeq _ NIL, member: SB.Member _ NIL, iVwr: IndividualViewers ]; LeagueViewers: TYPE = RECORD [ read: Labels.Label _ NIL, write: Labels.Label _ NIL, file: ViewerClasses.Viewer _ NIL, year: ViewerClasses.Viewer _ NIL, time: ViewerClasses.Viewer _ NIL, players: ViewerClasses.Viewer _ NIL, keeps: ViewerClasses.Viewer _ NIL, males: ViewerClasses.Viewer _ NIL, females: ViewerClasses.Viewer _ NIL, paid: ViewerClasses.Viewer _ NIL, unpaid: ViewerClasses.Viewer _ NIL, dolIn: ViewerClasses.Viewer _ NIL, dolOut: ViewerClasses.Viewer _ NIL ]; TeamViewersSeq: TYPE = REF TeamViewersRec; TeamViewersRec: TYPE = RECORD[SEQUENCE size: CARDINAL OF TeamViewers]; TeamViewers: TYPE = RECORD [ dIndex: ViewerClasses.Viewer _ NIL, players: ViewerClasses.Viewer _ NIL, keeps: ViewerClasses.Viewer _ NIL, males: ViewerClasses.Viewer _ NIL, females: ViewerClasses.Viewer _ NIL, points: ViewerClasses.Viewer _ NIL, prtctd: ViewerClasses.Viewer _ NIL ]; IndividualViewers: TYPE = RECORD [ edited: Labels.Label _ NIL, name: ViewerClasses.Viewer _ NIL, sse: ViewerClasses.Viewer _ NIL, type: ViewerClasses.Viewer _ NIL, rating: ViewerClasses.Viewer _ NIL, team: ViewerClasses.Viewer _ NIL, paid: ViewerClasses.Viewer _ NIL, group: ViewerClasses.Viewer _ NIL, shirt: ViewerClasses.Viewer _ NIL, sex: ViewerClasses.Viewer _ NIL, addr: ViewerClasses.Viewer _ NIL, tnum: ViewerClasses.Viewer _ NIL, pos: ViewerClasses.Viewer _ NIL, atten: ViewerClasses.Viewer _ NIL, comnt: ViewerClasses.Viewer _ NIL, dIndex: ViewerClasses.Viewer _ NIL ]; entryHeight: CARDINAL = 15; entryVSpace: CARDINAL = 2; entryLeftBias: CARDINAL _ 5; dataFont: VFonts.Font _ VFonts.EstablishFont["TimesRoman", 10, FALSE]; labelFont: VFonts.Font _ VFonts.EstablishFont["TimesRoman", 10, TRUE]; MakeSBTool: Commander.CommandProc = { tool: SBToolHandle _ NEW[SBToolRec]; comlist: LIST OF Rope.ROPE _ CommandTool.ParseToList[cmd].list; tool.file _ IF comlist#NIL THEN comlist.first ELSE NIL; tool.outer _ Containers.Create[[ name: "Softball Tool", iconic: FALSE, column: left, menu: Menus.CreateMenu[], scrollable: TRUE ]]; Menus.AppendMenuEntry[ menu: tool.outer.menu, entry: Menus.CreateEntry[ name: "Update", proc: RePaint, clientData: tool ] ]; tool.league _ NIL; tool.height _ entryHeight + entryVSpace; BVwr ["ReadFile", 0, 0, LeagueRead, tool]; tool.lVwr.write _ LVwr ["WriteFile", 0, 40, 60, 20, LeagueWrite, tool]; tool.lVwr.file _ TVwr ["File:", 1, 0, 10, 70, LeagueFile, tool]; tool.lVwr.year _ TVwr ["Year:", 2, 0, 10, 10, LeagueYear, tool]; tool.lVwr.time _ DVwr ["Time:", 2, 20, 30, 40, RePaint, tool]; tool.lVwr.players _ DVwr ["Players:", 3, 0, 10, 10, RePaint, tool]; tool.lVwr.keeps _ DVwr ["Keeps:", 4, 0, 10, 10, RePaint, tool]; tool.lVwr.males _ DVwr ["Males:", 3, 20, 30, 10, RePaint, tool]; tool.lVwr.females _ DVwr ["Females:", 4, 20, 30, 10, RePaint, tool]; tool.lVwr.paid _ DVwr ["Paid:", 3, 40, 50, 10, RePaint, tool]; tool.lVwr.unpaid _ DVwr ["Unpaid:", 4, 40, 50, 10, RePaint, tool]; tool.lVwr.dolIn _ DVwr ["$ paid:", 3, 60, 70, 10, RePaint, tool]; tool.lVwr.dolOut _ DVwr ["$ owed:", 4, 60, 70, 10, RePaint, tool]; tool.height _ tool.height + (5+2)*(entryHeight + entryVSpace); BVwr ["Marry", 0, 0, PlayerMarry, tool]; BVwr ["Divorce", 0, 10, PlayerDivorce, tool]; BVwr ["Add", 0, 20, PlayerAddNew, tool]; BVwr ["Del", 0, 30, PlayerDelOld, tool]; IBVwr ["Draft", 0, 40, Draft, tool, 20]; BVwr ["Undo", 0, 50, PlayerUnDo, tool]; tool.iVwr.edited _ LVwr ["Mod", 0, 60, 65, 10, PlayerCngOld, tool]; tool.iVwr.name _ TVwr ["Name:", 1, 0, 10, 30, PlayerName, tool]; tool.iVwr.sse _ TVwr ["Mate:", 1, 40, 50, 30, PlayerSSE, tool]; tool.iVwr.team _ DVwr ["Team:", 2, 0, 10, 30, PlayerTeam, tool]; tool.iVwr.sex _ DVwr ["Sex:", 2, 40, 50, 10, PlayerSex, tool]; tool.iVwr.type _ DVwr ["Type:", 2, 60, 70, 20, PlayerType, tool]; tool.iVwr.rating _ DVwr ["Rating:", 3, 0, 10, 10, PlayerRating, tool]; tool.iVwr.shirt _ DVwr ["Shirt:", 3, 20, 30, 10, PlayerShirt, tool]; tool.iVwr.paid _ DVwr ["Paid:", 3, 40, 50, 10, PlayerPaid, tool]; tool.iVwr.group _ DVwr ["Group:", 3, 60, 70, 20, PlayerGroup, tool]; tool.iVwr.dIndex _ TVwr ["DIndex:", 4, 0, 10, 30, PlayerDIndex, tool]; tool.iVwr.pos _ TVwr ["Pos:", 4, 40, 50, 10, PlayerPos, tool]; tool.iVwr.atten _ TVwr ["Atten:", 4, 60, 70, 20, PlayerAtten, tool]; tool.iVwr.addr _ TVwr ["Addr:", 5, 0, 10, 30, PlayerAddr, tool]; tool.iVwr.tnum _ TVwr ["Tel:", 5, 40, 50, 30, PlayerTNum, tool]; tool.iVwr.comnt _ TVwr ["Cmnt:", 6, 0, 10, 60, PlayerComnt, tool]; tool.height _ tool.height + (7+1)*(entryHeight + entryVSpace); ViewerOps.SetOpenHeight[tool.outer, tool.height]; -- hint our desired height ViewerOps.PaintViewer[tool.outer, all]; -- reflect above change; IF tool.file=NIL THEN { year: [86..150] _ BasicTime.Unpack[BasicTime.Now[]].year-1900; tool.file _ IO.PutFR["SB%g.sum", IO.int[year]]}; tool.file _ FileNames.ConvertToSlashFormat[FS.ExpandName[tool.file].fullFName]; SetTVwr[tool.lVwr.file, tool.file] }; AVwr: PROC[row, tCol, tWid: CARDINAL, handle: SBToolHandle] RETURNS[textViewer: ViewerClasses.Viewer] = { textViewer _ ViewerTools.MakeNewTextViewer[ [ parent: handle.outer, wx: tCol*VFonts.CharWidth['0] + entryLeftBias, ww: tWid*VFonts.CharWidth['0], wy: row* (entryHeight + entryVSpace)+1 + handle.height, wh: entryHeight, scrollable: FALSE, border: FALSE]]; ViewerTools.InhibitUserEdits[textViewer]}; IHdlRec: TYPE = RECORD[team: SB.Team, handle: SBToolHandle]; IBVwr: PROC[name: Rope.ROPE, row, lCol: CARDINAL, proc: Buttons.ButtonProc, handle: SBToolHandle, team: SB.Team] = { button: Buttons.Button _ Buttons.Create[ info: [ name: name, parent: handle.outer, wx: lCol*VFonts.CharWidth['0] + entryLeftBias, wy: row* (entryHeight + entryVSpace) + handle.height, wh: entryHeight, border: FALSE ], proc: proc, guarded: FALSE, font: labelFont, clientData: NEW[IHdlRec_[team, handle]] ]; }; BVwr: PROC[name: Rope.ROPE, row, lCol: CARDINAL, proc: Buttons.ButtonProc, handle: SBToolHandle] = { button: Buttons.Button _ Buttons.Create[ info: [ name: name, parent: handle.outer, wx: lCol*VFonts.CharWidth['0] + entryLeftBias, wy: row* (entryHeight + entryVSpace) + handle.height, wh: entryHeight, border: FALSE ], proc: proc, guarded: FALSE, font: labelFont, clientData: handle]; }; DVwr: PROC [name: Rope.ROPE, row, bCol, tCol, tWid: CARDINAL, proc: Buttons.ButtonProc, handle: SBToolHandle] RETURNS[textViewer: ViewerClasses.Viewer] = {RETURN[TVwr[name, row, bCol, tCol, tWid, proc, handle, TRUE]]}; TVwr: PROC [name: Rope.ROPE, row, bCol, tCol, tWid: CARDINAL, proc: Buttons.ButtonProc, handle: SBToolHandle, noEdit: BOOL _ FALSE] RETURNS[textViewer: ViewerClasses.Viewer] = { button: Buttons.Button _ Buttons.Create[ info: [ name: name, parent: handle.outer, wx: bCol*VFonts.CharWidth['0] + entryLeftBias, wy: row* (entryHeight + entryVSpace) + handle.height, wh: entryHeight, border: FALSE ], guarded: FALSE, font: labelFont, proc: proc, clientData: handle]; textViewer _ ViewerTools.MakeNewTextViewer[ [ parent: handle.outer, wx: tCol*VFonts.CharWidth['0] + entryLeftBias, ww: tWid*VFonts.CharWidth['0], wy: row* (entryHeight + entryVSpace)+1 + handle.height, wh: entryHeight, scrollable: FALSE, border: FALSE]]; IF noEdit THEN ViewerTools.InhibitUserEdits[textViewer]}; LVwr: PROC [name: Rope.ROPE, row, bCol, tCol, tWid: CARDINAL, proc: Buttons.ButtonProc, handle: SBToolHandle] RETURNS[textViewer: ViewerClasses.Viewer] = { button: Buttons.Button _ Buttons.Create[ info: [ name: name, parent: handle.outer, wx: bCol*VFonts.CharWidth['0] + entryLeftBias, wy: row* (entryHeight + entryVSpace) + handle.height, wh: entryHeight, border: TRUE ], guarded: FALSE, font: labelFont, proc: proc, clientData: handle]; textViewer _ Labels.Create[ [ parent: handle.outer, wx: tCol*VFonts.CharWidth['0] + entryLeftBias, ww: tWid*VFonts.CharWidth['0], wy: row* (entryHeight + entryVSpace)+1 + handle.height, wh: entryHeight, border: FALSE]] }; SetTVwr: PROC[viewer: ViewerClasses.Viewer, contents: Rope.ROPE] = {ViewerTools.SetContents[viewer, contents]}; SetLVwr: PROC[label: Labels.Label, contents: Rope.ROPE] ={Labels.Set[label, contents]}; RePaint: Menus.MenuProc = { RePaintLeague [parent, clientData]; RePaintTeams [parent, clientData]; RePaintMember [parent, clientData]}; RePaintLeague: Menus.MenuProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; IF league=NIL THEN RETURN; SetTVwr[sbTool.lVwr.file, league.file]; SetTVwr[sbTool.lVwr.year, IO.PutFR["%3g",IO.card[league.year]]]; SetLVwr[sbTool.lVwr.time, IO.PutR[IO.time[league.time]]]; SetLVwr[sbTool.lVwr.players, IO.PutFR["%3g",IO.card[league.players]]]; SetLVwr[sbTool.lVwr.keeps, IO.PutFR["%3g",IO.card[league.keeps]]]; SetLVwr[sbTool.lVwr.males, IO.PutFR["%3g",IO.card[league.males]]]; SetLVwr[sbTool.lVwr.females, IO.PutFR["%3g",IO.card[league.females]]]; SetLVwr[sbTool.lVwr.paid, IO.PutFR["%3g",IO.card[league.paid]]]; SetLVwr[sbTool.lVwr.unpaid, IO.PutFR["%3g",IO.card[league.unpaid]]]; SetLVwr[sbTool.lVwr.dolIn, IO.PutFR["%4g",IO.card[league.dollarsIn]]]; SetLVwr[sbTool.lVwr.dolOut, IO.PutFR["%4g",IO.card[league.dollarsOut]]] }; RePaintTeams: Menus.MenuProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; team: SB.Team _ sbTool.team; IF league=NIL THEN RETURN; FOR t: CARDINAL IN [0..sbTool.tVwr.size) DO SetLVwr[sbTool.tVwr[t].players, IO.PutFR["%3g",IO.card[league.teamStats[t].players]]]; SetLVwr[sbTool.tVwr[t].keeps, IO.PutFR["%3g",IO.card[league.teamStats[t].keeps]]]; SetLVwr[sbTool.tVwr[t].males, IO.PutFR["%3g",IO.card[league.teamStats[t].males]]]; SetLVwr[sbTool.tVwr[t].females, IO.PutFR["%3g",IO.card[league.teamStats[t].females]]]; SetLVwr[sbTool.tVwr[t].points, IO.PutFR["%3g",IO.card[league.teamStats[t].points]]]; SetLVwr[sbTool.tVwr[t].prtctd, IO.PutFR["%3g",IO.card[league.teamStats[t].prtctd]]]; SetTVwr[sbTool.tVwr[t].dIndex, IO.PutFR["%3g%g", IO.card[league.teamStats[t].dIndex], IO.rope[IF t = league.nextDTeam THEN " <" ELSE ""] ]]; ENDLOOP}; NULLMember: SB.Member _ NEW[SB.MemberRec _ [ ] ]; RePaintMember: Menus.MenuProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; mem: SB.Member _ sbTool.member; IF league=NIL THEN RETURN; IF mem=NIL THEN mem _ NULLMember; SetTVwr[ sbTool.iVwr.name, mem.fname.Cat [" ", mem.lname]]; SetTVwr[ sbTool.iVwr.sse, (IF mem.sse#NIL THEN mem.sse.fname.Cat[" ", mem.sse.lname] ELSE NIL)]; SetTVwr[sbTool.iVwr.team, league.teamNms [LOOPHOLE[mem.team]]]; SetTVwr[sbTool.iVwr.sex, league.sexNms [LOOPHOLE[mem.sex]]]; SetTVwr[sbTool.iVwr.type, league.typeNms [LOOPHOLE[mem.type]]]; SetTVwr[sbTool.iVwr.rating, league.ratingNms [LOOPHOLE[mem.rating]]]; SetTVwr[sbTool.iVwr.shirt, league.shirtNms [LOOPHOLE[mem.shirt]]]; SetTVwr[sbTool.iVwr.group, league.groupNms [LOOPHOLE[mem.group]]]; SetTVwr[sbTool.iVwr.paid, league.paidNms [LOOPHOLE[mem.paid]]]; SetTVwr[sbTool.iVwr.dIndex, IO.PutFR["%3g",IO.card[mem.dIndex]]]; SetTVwr[sbTool.iVwr.pos, mem.pos]; SetTVwr[sbTool.iVwr.atten, mem.atten]; SetTVwr[sbTool.iVwr.addr, mem.addr]; SetTVwr[sbTool.iVwr.tnum, mem.tnum]; SetTVwr[sbTool.iVwr.comnt, mem.comnt] }; LeagueRead: Buttons.ButtonProc = { league: SB.League; sbTool: SBToolHandle _ NARROW[clientData]; sbTool.file _ ViewerTools.GetContents[sbTool.lVwr.file]; league _ SB.ReadLeagueFile[sbTool.file]; IF league=NIL THEN { MessageWindow.Append[message: "File not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; sbTool.league _ league; sbTool.team _ 0; sbTool.member _ sbTool.league.members.first; IF sbTool.tVwr=NIL OR (sbTool.tVwr#NIL AND sbTool.tVwr.size#league.teamNms.size) THEN { IF sbTool.tVwr=NIL THEN { BVwr ["Team", 0, 0, Dummy, sbTool]; BVwr ["Players", 0, 17, Dummy, sbTool]; BVwr ["Keeps", 0, 26, Dummy, sbTool]; BVwr ["Males", 0, 33, Dummy, sbTool]; BVwr ["Females", 0, 41, Dummy, sbTool]; BVwr ["Points", 0, 50, Dummy, sbTool]; BVwr ["Prtctd", 0, 57, Dummy, sbTool]; BVwr ["DIndex", 0, 65, Dummy, sbTool]; sbTool.height _ sbTool.height + 2*(entryHeight + entryVSpace) } ELSE { FOR t: CARDINAL IN [0..sbTool.tVwr.size) DO ViewerOps.DestroyViewer[sbTool.tVwr[t].players ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].keeps ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].males ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].females ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].points ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].prtctd ]; ViewerOps.DestroyViewer[sbTool.tVwr[t].dIndex ]; ENDLOOP; sbTool.height _ sbTool.height - (sbTool.tVwr.size+2)*(entryHeight + entryVSpace) }; sbTool.tVwr _ NEW[TeamViewersRec[league.teamNms.size]]; FOR t: CARDINAL IN [0..sbTool.tVwr.size) DO IBVwr [league.teamNms[t], 0, 0, Draft, sbTool, t]; sbTool.tVwr[t].players _ AVwr [0, 20, 8, sbTool]; sbTool.tVwr[t].keeps _ AVwr [0, 28, 8, sbTool]; sbTool.tVwr[t].males _ AVwr [0, 36, 8, sbTool]; sbTool.tVwr[t].females _ AVwr [0, 44, 8, sbTool]; sbTool.tVwr[t].points _ AVwr [0, 52, 8, sbTool]; sbTool.tVwr[t].prtctd _ AVwr [0, 60, 8, sbTool]; sbTool.tVwr[t].dIndex _ AVwr [0, 68, 8, sbTool]; sbTool.height _ sbTool.height + (entryHeight + entryVSpace); ENDLOOP; sbTool.height _ sbTool.height + 2*(entryHeight + entryVSpace); ViewerOps.SetOpenHeight[sbTool.outer, sbTool.height] }; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, ""] }; LeagueWrite: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; sbTool.league.file _ ViewerTools.GetContents[sbTool.lVwr.file]; sbTool.league.year _ Convert.CardFromRope[ViewerTools.GetContents[sbTool.lVwr.year]]; SB.Update[sbTool.league]; SB.WriteLeagueFiles[sbTool.league]; SetLVwr[sbTool.lVwr.write, ""] }; LeagueFile: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.lVwr.file] }; LeagueYear: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.lVwr.year] }; Dummy: Buttons.ButtonProc = { }; PlayerFindM: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; IF league=NIL THEN RETURN; SELECT mouseButton FROM red => { m: LIST OF SB.Member; FOR m _ league.members, m.rest WHILE m.rest#NIL DO IF m.first#sbTool.member THEN LOOP; sbTool.member _ m.rest.first; EXIT REPEAT FINISHED => sbTool.member _ league.members.first ENDLOOP}; yellow => { rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member = NIL THEN member _ SB.FindMemberName[league, rec.lname]; IF member = NIL THEN member _ SB.FindMemberName[league, rec.fname]; IF member = NIL THEN { FOR lst: LIST OF SB.Member _ league.members, lst.rest WHILE lst#NIL DO subStr: Rope.ROPE _ Rope.Substr[lst.first.lname, 0, Rope.Length[rec.lname]]; IF ~Rope.Equal[subStr, rec.lname, FALSE] THEN LOOP; member _ lst.first; EXIT ENDLOOP}; IF member = NIL THEN { FOR lst: LIST OF SB.Member _ league.members, lst.rest WHILE lst#NIL DO aChar: CHAR _ lst.first.lname.Fetch[0]; bChar: CHAR _ rec.lname.Fetch[0]; IF aChar <= 'Z AND aChar >= 'A THEN aChar _ aChar + ('a-'A); IF bChar <= 'Z AND bChar >= 'A THEN bChar _ bChar + ('a-'A); IF aChar < bChar THEN LOOP; member _ lst.first; EXIT ENDLOOP; IF member = NIL THEN member _ league.members.first; MessageWindow.Append[message: "Not found.", clearFirst: TRUE]; MessageWindow.Blink[]}; IF member # NIL THEN sbTool.member _ member}; ENDCASE => { m: LIST OF SB.Member; FOR m _ league.members, m.rest WHILE m.rest#NIL DO IF m.rest.first#sbTool.member THEN LOOP; sbTool.member _ m.first; EXIT REPEAT FINISHED => sbTool.member _ m.first ENDLOOP}; RePaintMember[parent, clientData]; SetLVwr[sbTool.iVwr.edited, ""] }; PlayerNextMate: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; mem: SB.Member _ sbTool.member; IF league=NIL THEN RETURN; IF mem=NIL THEN RETURN; IF mem.sse=NIL THEN RETURN; sbTool.member _ mem.sse; RePaintMember[parent, clientData]; SetLVwr[sbTool.iVwr.edited, ""] }; ScanType: TYPE = {name, sse, team, sex, type, rating, shirt, paid, group, dIndex}; Scan: PROC[parent, clientData: REF, mouseButton: Menus.MouseButton, stype: ScanType] = { match: PROC[m: SB.Member] RETURNS[BOOL] = { RETURN[ SELECT stype FROM team => rec.team = m.team, sex => rec.sex = m.sex, type => rec.type = m.type, rating => rec.rating = m.rating, shirt => rec.shirt = m.shirt, paid => rec.paid = m.paid, group => rec.group = m.group, ENDCASE => ERROR ]}; sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; m: LIST OF SB.Member; mem: SB.Member; first: SB.Member _ NIL; prev: SB.Member _ NIL; next: SB.Member _ NIL; last: SB.Member _ NIL; rec: SB.MemberRec; IF league=NIL THEN RETURN; IF stype = dIndex THEN {ScanDIndex [NARROW[parent], clientData, mouseButton]; RETURN}; IF stype = name THEN {PlayerFindM [NARROW[parent], clientData, mouseButton]; RETURN}; IF stype = sse THEN {PlayerNextMate [NARROW[parent], clientData, mouseButton]; RETURN}; [mem, rec] _ ExtractIndividualViewerFields[sbTool]; IF mem=NIL THEN mem _ league.members.first; FOR m _ league.members, m.rest WHILE m.first#mem DO IF ~match[m.first] THEN LOOP; IF first = NIL THEN first _ m.first; prev _ m.first ENDLOOP; FOR m _ m.rest, m.rest WHILE m#NIL DO IF ~match[m.first] THEN LOOP; IF next = NIL THEN next _ m.first; last _ m.first ENDLOOP; SELECT mouseButton FROM red => sbTool.member _ IF next#NIL THEN next ELSE first; yellow => { }; ENDCASE => sbTool.member _ IF prev#NIL THEN prev ELSE last; RePaintMember[NARROW[parent], clientData]; SetLVwr[sbTool.iVwr.edited, ""] }; ScanDIndex: PROC[parent, clientData: REF, mouseButton: Menus.MouseButton] = { match: PROC[m: SB.Member] RETURNS[BOOL] = { RETURN[ SELECT mouseButton FROM red => rec.dIndex+1 = m.dIndex, yellow => rec.dIndex = m.dIndex, ENDCASE => rec.dIndex = m.dIndex+1]}; sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; mem: SB.Member; rec: SB.MemberRec; IF league=NIL THEN RETURN; rec _ ExtractIndividualViewerFields[sbTool].rec; FOR m: LIST OF SB.Member _ league.members, m.rest WHILE m#NIL DO IF ~match[m.first] THEN LOOP; mem _ m.first; EXIT ENDLOOP; IF mem=NIL THEN { MessageWindow.Append[message: "Not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; sbTool.member _ mem; RePaintMember[NARROW[parent], clientData]; SetLVwr[sbTool.iVwr.edited, ""] }; ActionRec: TYPE = RECORD[action: Action, ref: REF]; Action: TYPE = {add, del, divorce, marry, draft}; Actions: TYPE = LIST OF ActionRec; actions: Actions _ NIL; PlayerMarry: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member=NIL THEN { MessageWindow.Append[message: "Member not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF rec.sse=NIL THEN { MessageWindow.Append[message: "Mate not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#NIL AND member.sse#rec.sse THEN { MessageWindow.Append[message: "Member is already spoken for.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF rec.sse.sse#NIL AND rec.sse.sse#member THEN { MessageWindow.Append[message: "Mate is already spoken for.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; rec.sse.sse _ member; member.sse _ rec.sse; member.pair _ rec.sse.pair _ paired; MessageWindow.Append[message: "Sniff sniff.", clearFirst: TRUE]; sbTool.member _ member; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; PlayerDivorce: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member=NIL THEN { MessageWindow.Append[message: "Member not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF rec.sse=NIL THEN { MessageWindow.Append[message: "Mate not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#rec.sse OR rec.sse.sse#member THEN { MessageWindow.Append[message: "They are not married.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; rec.sse.sse _ NIL; member.sse _ NIL; member.pair _ rec.sse.pair _ sgl; MessageWindow.Append[message: "Oh Lord! Free at last!", clearFirst: TRUE]; sbTool.member _ member; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; PlayerAddNew: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member#NIL THEN { MessageWindow.Append[message: "Old player. Not changed.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF rec.sse#NIL AND rec.sse.sse#NIL THEN { MessageWindow.Append[message: "Mate is already engaged. Not added.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; member _ NEW[SB.MemberRec _ rec]; SB.AddMember[league, member]; IF rec.sse#NIL THEN rec.sse.sse _ member; IF rec.sse#NIL THEN MessageWindow.Append[message: "Added 2 members", clearFirst: TRUE] ELSE MessageWindow.Append[message: "Added 1 member", clearFirst: TRUE]; sbTool.member _ member; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; PlayerDelOld: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; first: SB.Member _ NIL; prev: SB.Member _ NIL; next: SB.Member _ NIL; last: SB.Member _ NIL; rec: SB.MemberRec; m: LIST OF SB.Member; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member=NIL THEN { MessageWindow.Append[message: "Player not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#NIL THEN {member.sse.pair _ sgl; member.sse.sse _ NIL}; FOR m _ league.members, m.rest WHILE m.first#member DO IF first = NIL THEN first _ m.first; prev _ m.first ENDLOOP; FOR m _ m.rest, m.rest WHILE m#NIL DO IF next = NIL THEN next _ m.first; last _ m.first ENDLOOP; SELECT mouseButton FROM red => sbTool.member _ IF next#NIL THEN next ELSE first; yellow => { }; ENDCASE => sbTool.member _ IF prev#NIL THEN prev ELSE last; actions _ CONS[[del, member], actions]; SB.DeleteMember[league, member]; MessageWindow.Append[message: "Deleted member", clearFirst: TRUE]; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; Draft: Buttons.ButtonProc = { data: REF IHdlRec _ NARROW[clientData]; sbTool: SBToolHandle _ data.handle; team: SB.Team _ data.team; league: SB.League _ sbTool.league; member: SB.Member _ NIL; rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF team=20 THEN team _ league.nextDTeam; SELECT mouseButton FROM red, blue => { SetTVwr[sbTool.iVwr.team, league.teamNms [LOOPHOLE[team]]]; Scan[ parent, sbTool, mouseButton, team]; RETURN } ENDCASE; IF member=NIL THEN { MessageWindow.Append[message: "Member not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF team#0 THEN{ IF member.team#0 THEN { MessageWindow.Append[message: "Already drafted.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#NIL AND member.sse.team#0 THEN { MessageWindow.Append[message: "Spouse already drafted.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; member.team _ team; member.dIndex _ league.nextDIndex; IF member.sse=NIL THEN MessageWindow.Append[message: "Drafted", clearFirst: TRUE] ELSE { member.sse.team _ team; member.sse.dIndex _ IF team#0 THEN league.nextDIndex+1 ELSE 0; MessageWindow.Append[message: "Pair Drafted", clearFirst: TRUE]} } ELSE { lastIndex: CARDINAL _ member.dIndex; IF member.team=0 THEN { MessageWindow.Append[message: "Already unassigned.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#NIL AND member.sse.team=0 THEN { MessageWindow.Append[message: "Spouse already unassigned.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; member.team _ team; member.dIndex _ 0; IF member.sse=NIL THEN MessageWindow.Append[message: "Unassigned", clearFirst: TRUE] ELSE { lastIndex _ MIN[ member.dIndex, lastIndex]; lastIndex _ MAX[ 1, lastIndex]-1; member.sse.team _ team; member.sse.dIndex _ IF team#0 THEN league.nextDIndex+1 ELSE 0; MessageWindow.Append[message: "Pair Unassigned", clearFirst: TRUE]}}; sbTool.member _ member; SB.Update[league]; RePaint[parent, sbTool]; SetLVwr[sbTool.lVwr.write, "edited"] }; PlayerUnDo: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; IF league=NIL THEN RETURN; IF actions=NIL THEN { MessageWindow.Append[message: "No actions.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; SELECT actions.first.action FROM add => { sbTool.member _ NARROW[actions.first.ref]; actions _ actions.rest; RePaint[parent, clientData]; PlayerDelOld[parent, clientData, red, control]}; del => { sbTool.member _ NARROW[actions.first.ref]; actions _ actions.rest; MessageWindow.Append[message: "Un delete", clearFirst: TRUE]; IF sbTool.member.sse#NIL THEN IF sbTool.member.sse.sse#NIL AND sbTool.member.sse.sse#sbTool.member THEN {sbTool.member.pair _ sgl; sbTool.member.sse _ NIL} ELSE { sbTool.member.sse.pair _ paired; sbTool.member.sse.sse _ sbTool.member; MessageWindow.Append[message: " and remarry", clearFirst: FALSE] }; SB.AddMember[league, sbTool.member]}; ENDCASE => { MessageWindow.Append[message: "Action is not reversible.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; PlayerCngOld: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; league: SB.League _ sbTool.league; member: SB.Member _ NIL; rec: SB.MemberRec; [member, rec] _ ExtractIndividualViewerFields[sbTool]; IF member=NIL THEN { MessageWindow.Append[message: "Player not found.", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; IF member.sse#rec.sse THEN { MessageWindow.Append[message: "Mating operations must be explicit", clearFirst: TRUE]; MessageWindow.Blink[]; RETURN}; member^ _ rec; MessageWindow.Append[message: "Done", clearFirst: TRUE]; sbTool.member _ member; SB.Update[league]; RePaint[parent, clientData]; SetLVwr[sbTool.lVwr.write, "edited"] }; ExtractIndividualViewerFields: PROC[sbTool: SBToolHandle] RETURNS[mem: SB.Member, rec: SB.MemberRec] = { league: SB.League _ sbTool.league; sseFName: Rope.ROPE; sseLName: Rope.ROPE; [rec.fname, rec.lname] _ ParseName[ViewerTools.GetContents[sbTool.iVwr.name]]; mem _ SB.FindMember[league, rec.lname, rec.fname]; [sseFName, sseLName] _ ParseName[ViewerTools.GetContents[sbTool.iVwr.sse]]; rec.sse _ SB.FindMember[league, sseLName, sseFName]; IF rec.sse#NIL THEN rec.pair _ paired ELSE rec.pair _ sgl; rec.type _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.type], league.typeNms]]; rec.rating _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.rating], league.ratingNms]]; rec.team _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.team], league.teamNms]]; rec.paid _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.paid], league.paidNms]]; rec.group _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.group], league.groupNms]]; rec.shirt _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.shirt], league.shirtNms]]; rec.sex _ LOOPHOLE[ SB.RopeSeqIndex[ViewerTools.GetContents[sbTool.iVwr.sex], league.sexNms]]; rec.addr _ ViewerTools.GetContents[sbTool.iVwr.addr]; rec.tnum _ ViewerTools.GetContents[sbTool.iVwr.tnum]; rec.pos _ ViewerTools.GetContents[sbTool.iVwr.pos]; rec.atten _ ViewerTools.GetContents[sbTool.iVwr.atten]; rec.comnt _ ViewerTools.GetContents[sbTool.iVwr.comnt]; rec.dIndex _ Convert.CardFromRope[ViewerTools.GetContents[sbTool.iVwr.dIndex]] }; PlayerName: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, name] ELSE ViewerTools.SetSelection[sbTool.iVwr.name] }; PlayerSSE: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, sse] ELSE ViewerTools.SetSelection[sbTool.iVwr.sse] }; PlayerTeam: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, team] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.team, sbTool.league.teamNms] }; PlayerSex: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, sex] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.sex, sbTool.league.sexNms] }; PlayerType: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, type] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.type, sbTool.league.typeNms] }; PlayerRating: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, rating] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.rating, sbTool.league.ratingNms] }; PlayerShirt: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, shirt] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.shirt, sbTool.league.shirtNms] }; PlayerPaid: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, paid] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.paid, sbTool.league.paidNms] }; PlayerGroup: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, group] ELSE IncVwrSeq[mouseButton, sbTool.iVwr.group, sbTool.league.groupNms] }; PlayerDIndex: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; IF shift THEN Scan[ parent, clientData, mouseButton, dIndex] ELSE ViewerTools.SetSelection[sbTool.iVwr.dIndex] }; PlayerPos: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.iVwr.pos] }; PlayerAtten: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.iVwr.atten] }; PlayerAddr: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.iVwr.addr] }; PlayerTNum: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.iVwr.tnum] }; PlayerComnt: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; ViewerTools.SetSelection[sbTool.iVwr.comnt] }; IncVwrSeq: PROC [mouse: Menus.MouseButton, viewer: ViewerClasses.Viewer, seq: SB.RopeSeq] = { index: CARDINAL _ SB.RopeSeqIndex[ViewerTools.GetContents[viewer], seq]; SetTVwr[viewer, seq[CardModMouse[mouse, index, seq.size]]] }; CardModMouse: PROC[mouseButton: Menus.MouseButton, val, mod: CARDINAL] RETURNS[result: CARDINAL] = { SELECT mouseButton FROM red => {result _ (val +1) MOD mod}; yellow => {result _ val}; ENDCASE => {result _ (val+mod-1) MOD mod} }; ParseName: PROC[rope: Rope.ROPE] RETURNS[first, last: Rope.ROPE] = { temp: Rope.ROPE; in: IO.STREAM _ IO.RIS[rope]; DO last _ first _ NIL; last _ IO.GetTokenRope[in ! IO.EndOfStream => {last _ NIL; EXIT}].token; first _ IO.GetTokenRope[in ! IO.EndOfStream => {first _ NIL; EXIT}].token; temp _ first; first _ last; last _ temp; EXIT; ENDLOOP }; Commander.Register[key: "SB", proc: MakeSBTool, doc: "Create a Softball tool" ]; END. SBTool.mesa removebutton CD; createbutton SB compile SBTool; run SBImpl SBTool; Last edited by Curry on April 23, 1986 8:45:39 pm PST Don Curry May 1, 1987 5:48:43 pm PDT Last Edited by: Don Curry May 28, 1987 11:36:14 am PDT set: Labels.Label _ NIL, team: ViewerClasses.Viewer _ NIL, BVwr ["Find", 0, 0, PlayerFindM, tool]; BVwr ["Team", 0, 8, PlayerNextT, tool]; BVwr ["Mate", 0, 16, PlayerNextMate, tool]; Buttons.ButtonProc = Menus.MenuProc = PROC [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] ; For menus, the parent field will contain the parent Viewer; for buttons, parent will be the button Viewer itself. Use NARROW to convert a REF ANY to a Viewer. MessageWindow.Append[message: "RePaint League", clearFirst: TRUE]; MessageWindow.Append[message: "RePaint Teams", clearFirst: TRUE]; SetLVwr[sbTool.tVwr[t].team, league.teamNms[t]]; MessageWindow.Append[message: "RePaint Member", clearFirst: TRUE]; ViewerOps.DestroyViewer[sbTool.tVwr[t].team ]; sbTool.tVwr[t].team _ AVwr [0, 0, 20, sbTool]; TeamNext: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; sbTool.team _ CardModMouse[mouseButton, sbTool.team, sbTool.league.teamNms.size]; RePaintTeams[parent, clientData] }; TeamSet: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; dIndexStr: Rope.ROPE _ ViewerTools.GetContents[sbTool.tVwr.dIndex]; SetLVwr[sbTool.tVwr.set, "done"] }; TeamDIndex: Buttons.ButtonProc = { sbTool: SBToolHandle _ NARROW[clientData]; current: CARDINAL _ sbTool.league.teamStats[sbTool.team].dIndex; current _ current + (SELECT mouseButton FROM red => 1, yellow => 0, ENDCASE => (IF current=0 THEN 0 ELSE -1)); sbTool.league.teamStats[sbTool.team].dIndex _ current; RePaintTeams[parent, clientData] }; name => rec.name = m.team, sse => rec.sse = m.team, dIndex => rec.dIndex = m.dIndex, ViewerTools.SetContents[sbTool.iVwr.dIndex, Convert.RopeFromCard[lastIndex]]; Scan[ parent, sbTool, mouseButton, dIndex] } }; -- too confusing Κ$Θ– "Cedar" style˜– "Cedar" stylešΠbl ™ JšœC™CJšœ5™5Icode™$K™6—J˜JšΟk œžœKžœc˜ΌJ˜šΡblnœžœžœ˜JšžœBžœ5žœ#˜₯—Jšž˜J˜JšΟb œžœžœ Οc$˜HJ˜š  œžœžœ˜Jšœžœ˜#Jšœžœ‘˜*Jšœžœ žœ˜Jšœ žœžœ˜Jšœ˜Jšœžœ ˜Jšœžœ˜Jšœžœ žœ˜Jšœ˜—J˜š  œžœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜#Jšœžœ˜#Jšœžœ˜#Jšœ!žœ˜%Jšœ žœ˜$Jšœ žœ˜$Jšœ!žœ˜%Jšœžœ˜#Jšœ žœ˜$Jšœ žœ˜$Jšœ žœ˜&—J˜Jš œžœžœ˜*Jš  œžœžœžœžœžœ˜Fš  œžœžœ˜Jšœžœ™Jšœžœ™#Jšœ žœ˜$Jšœ!žœ˜%Jšœ žœ˜$Jšœ žœ˜$Jšœ!žœ˜%Jšœ žœ˜$Jšœ žœ˜&—J˜š œžœžœ˜"Jšœžœ˜Jšœžœ˜"Jšœžœ˜!Jšœžœ˜"Jšœžœ˜#Jšœžœ˜"Jšœžœ˜"Jšœžœ˜"Jšœžœ˜#Jšœžœ˜!Jšœžœ˜"Jšœžœ˜"Jšœžœ˜!Jšœžœ˜#Jšœžœ˜"Jšœžœ˜%—J˜Jšœžœ˜Jšœžœ˜Jšœžœ˜J˜Jšœ@žœ˜GJšœ@žœ˜FJ˜šΠbn œ˜%Jšœžœ ˜&Jšœ žœžœžœ%˜@Jš œ žœžœ žœžœžœžœ˜8šœ ˜ Jšœ˜Jšœžœ˜Jšœ ˜ Jšœ˜Jšœ žœ˜—šœ˜Jšœ˜šœ˜Jšœ˜Jšœ˜Jšœ˜——Jšœžœ˜Jšœ(˜(J˜Jšœ8˜8JšœI˜IJšœF˜FJšœE˜EJšœC˜CJšœH˜HJšœE˜EJšœE˜EJšœH˜HJšœC˜CJšœF˜FJšœE˜EJšœF˜FJ˜Jšœ>˜>J˜Jšœ4™4Jšœ5™5Jšœ6™6Jšœ5˜5Jšœ7˜7Jšœ3˜3Jšœ3˜3Jšœ(žœ ˜6Jšœ3˜3JšœD˜DJ˜J˜J˜JšœC˜CJšœB˜BJšœC˜CJšœA˜AJšœC˜CJšœG˜GJšœF˜FJšœC˜CJšœE˜EJšœG˜GJšœA˜AJšœF˜FJšœC˜CJšœB˜BJšœD˜DJ™Jšœ>˜>J˜Jšœ2‘˜LJšœ+‘˜Cšžœ žœžœ˜Jšœ>˜>Jšœ žœžœ ˜0—Jšœ+žœ"˜OJšœ%˜%—˜J˜—šΟnœžœžœ˜;šžœ&˜-šœ-˜-Jšœ˜Jšœ0˜0Jšœ ˜ Jšœ9˜9Jšœ˜Jšœ žœ˜Jšœ žœ˜——Jšœ*˜*J˜—šœ žœžœ&˜Jšœ,žœ˜BJšœ.žœ˜EJšœ.žœ˜DJšœ,žœ˜BJšœ,žœ ˜AJšœžœ žœ˜AJšœ#˜#Jšœ&˜&Jšœ%˜%Jšœ$˜$Jšœ)˜)J˜—š£ œ˜"Jšœžœ˜Jšœžœ ˜*Jšœ8˜8Jšœ žœ˜)šžœžœžœ˜Jšœ=žœ˜CJšœ˜Jšžœ˜—Jšœ˜Jšœ˜Jšœ,˜,š žœ žœžœžœžœ'žœ˜Wšžœ ž˜šžœ˜Jšœ&˜&Jšœ'˜'Jšœ&˜&Jšœ&˜&Jšœ'˜'Jšœ'˜'Jšœ'˜'Jšœ&˜&Jšœ?˜?—šžœ˜šžœžœžœž˜+Jšœ/™/Jšœ1˜1Jšœ0˜0Jšœ0˜0Jšœ1˜1Jšœ1˜1Jšœ1˜1Jšœ0˜0Jšžœ˜—JšœS˜S——Jšœžœ&˜7šžœžœžœž˜+Jšœ3˜3Jšœ0™0Jšœ2˜2Jšœ0˜0Jšœ0˜0Jšœ2˜2Jšœ1˜1Jšœ1˜1Jšœ1˜1Jšœ<˜˜>Jšœ7˜7—Jšœ˜Jšœ!˜!—J˜J˜š£ œ˜#Jšœžœ ˜*Jšœ?˜?JšœU˜UJšžœ˜Jšžœ!˜#Jšœ!˜!—š£ œ˜"Jšœžœ ˜*Jšœ-˜-—š£ œ˜"Jšœžœ ˜*Jšœ-˜-—J˜Jš£œ˜ J˜šœ ™ Jšœžœ ™*JšœQ™QJšœ#™#—šœž™Jšœžœ ™*JšœC™CJšœ#™#—šœ"™"Jšœžœ ™*Jšœ žœ/™@šœžœ ž™,Jšœ ™ Jšœ ™ Jšžœžœ žœžœ™*—Jšœ6™6Jšœ#™#—J˜š£ œ˜#Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšžœžœžœžœ˜šžœ ž˜šœ ˜ Jšœžœžœžœ˜šžœžœžœž˜2Jšžœžœžœ˜#Jšœ˜Jšžœžœžœ)žœ˜F——šœ ˜ Jšœžœ ˜Jšœ6˜6Jšžœ žœžœ žœ#˜CJšžœ žœžœ žœ#˜Cšžœ žœžœ˜š žœžœžœžœ#žœžœž˜FJšœ žœ;˜LJšžœ žœžœžœ˜3Jšœžœžœ˜"——šžœ žœžœ˜š žœžœžœžœ#žœžœž˜FJšœžœ˜'Jšœžœ˜!Kšžœ žœ žœ˜Jšœ˜—Jšžœ žœžœ˜-—šžœ˜ Jšœžœžœžœ˜šžœžœžœž˜2Jšžœžœžœ˜(Jšœ˜Jšžœžœžœžœ˜9———Jšœ"˜"Jšœ"˜"—J˜š£œ˜&Jšœžœ ˜*Jšœžœ˜"Jšœžœ˜ Jšžœžœžœžœ˜Jšžœžœžœžœ˜Jšžœ žœžœžœ˜Jšœ˜Jšœ"˜"Jšœ"˜"—J˜Jšœ žœD˜RJ˜š£œžœžœ6˜Xš œžœžœ žœžœ˜+šžœžœž˜Jšœ™Jšœ™Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ˜Jšœ˜Jšœ ™ Jšžœžœ˜——Jšœžœ ˜*Jšœžœ˜"Jšœžœžœžœ˜Jšœžœ˜Jšœžœ žœ˜Jšœžœ žœ˜Jšœžœ žœ˜Jšœžœ žœ˜Jšœžœ ˜Jšžœžœžœžœ˜šžœž˜Jšœžœ$žœ˜A—šžœž˜Jšœžœ$žœ˜A—šžœž˜Jšœžœ$žœ˜C—Jšœ3˜3Jšžœžœžœ˜+šžœžœ ž˜3Jšžœžœžœ˜Jšžœ žœžœ˜$Jšœžœ˜—šžœžœžœž˜%Jšžœžœžœ˜Jšžœžœžœ˜"Jšœžœ˜—šžœ ž˜Jš œžœžœžœžœ˜:Jšœ˜Jš žœžœžœžœžœ˜;—Jšœ*˜*Jšœ"˜"—J˜š£ œžœžœ%˜Mš œžœžœ žœžœ˜+šžœžœ ž˜Jšœ!˜!Jšœ!˜!Jšžœ˜%——Jšœžœ ˜*Jšœžœ˜"Jšœžœ˜Jšœžœ ˜Jšžœžœžœžœ˜Jšœ0˜0š žœžœžœžœ!žœž˜@Jšžœžœžœ˜Jšœžœžœ˜—šžœžœžœ˜Jšœ8žœ˜>Jšœ˜Jšžœ˜—Jšœ˜Jšœ*˜*Jšœ"˜"—J˜Jšœ žœžœžœ˜3Jšœ žœ%˜2Jšœ žœžœžœ ˜#Jšœžœ˜J˜š£ œ˜%Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšœžœ ˜Jšœ6˜6šžœžœžœ˜Jšœ?žœ˜EJšœ˜Jšžœ˜—šžœ žœžœ˜Jšœ=žœ˜CJšœ˜Jšžœ˜—šžœ žœžœžœ˜/JšœKžœ˜QJšœ˜Jšžœ˜—šžœ žœžœžœ˜0JšœIžœ˜OJšœ˜Jšžœ˜—Jšœ˜Jšœ˜Jšœ$˜$Jšœ:žœ˜@Jšœ˜Jšžœ˜Jšœ˜Jšœ'˜'—J˜š£ œ˜'Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšœžœ ˜Jšœ6˜6šžœžœžœ˜Jšœ?žœ˜EJšœ˜Jšžœ˜—šžœ žœžœ˜Jšœ=žœ˜CJšœ˜Jšžœ˜—šžœžœžœ˜2JšœCžœ˜IJšœ˜Jšžœ˜—Jšœžœ˜Jšœ žœ˜Jšœ!˜!JšœEžœ˜KJšœ˜Jšžœ˜Jšœ˜Jšœ'˜'—J˜š£ œ˜&Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšœžœ ˜Jšœ6˜6šžœžœžœ˜JšœGžœ˜MJšœ˜Jšžœ˜—š žœ žœžœ žœžœ˜)JšœRžœ˜XJšœ˜Jšžœ˜—Jšœ žœžœ˜!Jšžœ˜Jšžœ žœžœ˜)šžœ ž˜Jšžœ>žœ˜GJšžœ=žœ˜G—Jšœ˜Jšžœ˜Jšœ˜Jšœ'˜'J˜—š£ œ˜&Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšœ žœ žœ˜Jšœžœ žœ˜Jšœžœ žœ˜Jšœžœ žœ˜Jšœžœ ˜Jšœžœžœžœ˜Jšœ6˜6šžœžœžœ˜Jšœ?žœ˜EJšœ˜Jšžœ˜—Jšžœ žœžœ*žœ˜Ešžœžœž˜6Jšžœ žœžœ˜$Jšœžœ˜—šžœžœžœž˜%Jšžœžœžœ˜"Jšœžœ˜—šžœ ž˜Jš œžœžœžœžœ˜:Jšœ˜Jš žœžœžœžœžœ˜;—Jšœ žœ˜'Jšžœ˜ Jšœ<žœ˜BJšžœ˜Jšœ˜Jšœ'˜'—J˜š£œ˜Jšœžœ ˜*Jšœ$˜$Jšœ˜Jšœ žœ˜#Jšœ žœ žœ˜Jšœžœ ˜Jšœ6˜6Jšžœ žœ˜(šžœ ž˜šœ˜Jšœ*žœ ˜;Jšœ)˜)Jšžœžœ˜——šžœžœžœ˜Jšœ?žœ˜EJšœ˜Jšžœ˜—šžœ˜ šžœ˜šžœžœ˜Jšœ>žœ˜DJšœ˜Jšžœ˜—šžœ žœžœžœ˜.JšœEžœ˜KJšœ˜Jšžœ˜—Jšœ˜Jšœ"˜"šžœ ž˜Jšžœ6žœ˜?šžœ˜Jšœ˜Jšœžœžœžœ˜>Jšœ:žœ˜B———šžœ˜Jšœ žœ˜$šžœžœ˜JšœAžœ˜GJšœ˜Jšžœ˜—šžœ žœžœžœ˜.JšœHžœ˜NJšœ˜Jšžœ˜—Jšœ˜Jšœ˜šžœ ž˜Jšžœ9žœ˜Bšžœ˜Jšœ žœ˜+Jšœ žœ˜!Jšœ˜Jšœžœžœžœ˜>Jšœ=žœ˜E—JšœM™MJšœ@™@———Jšœž˜Jšžœ˜Jšœ˜Jšœ'˜'—J˜š£ œ˜$Jšœžœ ˜+Jšœ žœ˜#Jšžœžœžœžœ˜šžœ ž˜šžœ˜Jšœ9žœ˜?Jšœ˜Jšžœ˜——šžœž˜ šœ ˜ Jšœžœ˜*Jšœ˜Jšœ˜Jšœ0˜0—šœ ˜ Jšœžœ˜*Jšœ˜Jšœ7žœ˜=šžœžœž˜šžœžœžœ$˜DJšžœ0žœ˜8šžœ˜Jšœ ˜ Jšœ&˜&Jšœ:žœ˜C———Jšžœ#˜%—šžœ˜ JšœGžœ˜MJšœ˜Jšžœ˜J˜——Jšžœ˜Jšœ˜Jšœ'˜'—J˜š£ œ˜&Jšœžœ ˜+Jšœ žœ˜#Jšœ žœ žœ˜Jšœžœ ˜Jšœ6˜6šžœžœžœ˜Jšœ?žœ˜EJšœ˜Jšžœ˜—šžœžœ˜JšœPžœ˜VJšœ˜Jšžœ˜—Jšœ˜Jšœ2žœ˜8Jšœ˜Jšžœ˜Jšœ˜Jšœ'˜'J˜—J˜š£œžœ˜9Jšžœžœžœ˜.Jšœ žœ˜#Jšœžœ˜Jšœžœ˜JšœN˜NJšœžœ*˜3JšœM˜MJšœ žœ(˜4Jšžœ žœžœžœ˜:šœ žœ˜JšžœJ˜L—šœ žœ˜JšžœN˜P—šœ žœ˜JšžœJ˜L—šœ žœ˜JšžœJ˜L—šœ žœ˜JšžœL˜N—šœ žœ˜JšžœL˜N—šœ žœ˜JšžœH˜J—Jšœ6˜6Jšœ6˜6Jšœ4˜4Jšœ8˜8Jšœ8˜8JšœQ˜Q—J˜š£ œ˜"Jšœžœ ˜*šžœ˜Jšžœ-˜1Jšžœ.˜2——š£ œ˜!Jšœžœ ˜*šžœ˜Jšžœ,˜0Jšžœ-˜1——š£ œ˜"Jšœžœ ˜*šžœ˜Jšžœ-˜1JšžœC˜G——š£ œ˜!Jšœžœ ˜*šžœ˜Jšžœ,˜0JšžœA˜E——š£ œ˜"Jšœžœ ˜*šžœ˜Jšžœ-˜1JšžœC˜G——š£ œ˜$Jšœžœ ˜*šžœ˜Jšžœ/˜3JšžœG˜K——š£ œ˜#Jšœžœ ˜*šžœ˜Jšžœ.˜2JšžœE˜I——š£ œ˜"Jšœžœ ˜*šžœ˜Jšžœ-˜1JšžœC˜G——š£ œ˜#Jšœžœ ˜*šžœ˜Jšžœ.˜2JšžœE˜I——J˜š£ œ˜$Jšœžœ ˜*šžœ˜Jšžœ/˜3Jšžœ0˜4——š£ œ˜!Jšœžœ ˜*Jšœ,˜,—š£ œ˜#Jšœžœ ˜*Jšœ.˜.—š£ œ˜"Jšœžœ ˜*Jšœ-˜-—š£ œ˜"Jšœžœ ˜*Jšœ-˜-—š£ œ˜#Jšœžœ ˜*Jšœ.˜.—J˜š£ œž˜Jšœ>žœ ˜MJšœžœžœ4˜HJšœ=˜=—J˜š£ œžœ+žœ˜FJšžœ žœ˜šžœ ž˜Jšœžœ˜&Jšœ˜Jšžœžœ˜,——J˜š £ œžœ žœžœžœ˜DJšœ žœ˜Jš œžœžœžœžœ˜šž˜Jšœžœ˜Jš œžœžœžœžœ ˜HJš œžœžœžœžœ ˜JJšœ)žœžœ˜9——J˜JšœP˜PJ˜Jšžœ˜—…—~œ«f