DIRECTORY AlpineEnvironment USING[ Property], AlpineFile USING [ PropertySet], Atom USING[ GetPName ], Buttons USING[ Button, ButtonProc, Create, Destroy, SetDisplayStyle ], Commander USING[ CommandProc, Register ], Containers USING[ ChildXBound, ChildYBound, Create ], IO, Labels USING[ Create ], MBQueue USING[ Create, CreateButton, Queue ], Rope, Rules USING[ Create ], TypeScript USING[ Create ], UserCredentials USING[ Get ], ViewerClasses USING[ Viewer ], ViewerIO USING[ CreateViewerStreams ], ViewerOps USING[ ComputeColumn, DestroyViewer, MoveViewer, SetOpenHeight ], ViewerTools USING[ GetContents, GetSelectedViewer, MakeNewTextViewer, SetContents, SetSelection], YodelData; YodelRoot: CEDAR MONITOR LOCKS d USING d: MyData IMPORTS Atom, Buttons, Commander, Containers, IO, Labels, MBQueue, Rope, Rules, TypeScript, UserCredentials, ViewerIO, ViewerOps, ViewerTools, YodelData EXPORTS YodelData = BEGIN OPEN YodelData ; NamePrefixes: LIST OF ROPE = LIST[ "Luther.Alpine", "Ebbetts.Alpine", "Ivy", "Indigo", "" ]; PropertySetToRopeArray: PUBLIC ARRAY [0..NumberOfAlpineProperties) OF PropertySetToRope _ [ [byteLength, "byteLength"], [createTime, "createTime"], [highWaterMark, "highWaterMark"], [modifyAccess, "modifyAccess"], [owner, "owner"], [readAccess, "readAccess"], [stringName, "stringName"], [version, "version"] ]; ROPE: TYPE = Rope.ROPE; Create: Commander.CommandProc = BEGIN d: MyData = NEW[MyDataObject ]; v: ViewerClasses.Viewer = Containers.Create[ info: [name: "Yodel", column: left, scrollable: FALSE, iconic: TRUE]]; BEGIN temp1: Buttons.Button = Buttons.Create[ info: [name: "Dest Server:", parent: v, border: FALSE, wx: 0, wy: 0], proc: NIL, clientData: d, fork: FALSE, paint: FALSE]; temp2: Buttons.Button = Buttons.Create[ info: [name: "highWaterMark", parent: v, border: FALSE, wx: 0, wy: 0], proc: NIL, clientData: d, fork: FALSE, paint: FALSE]; d.q _ MBQueue.Create[]; d.maxW _ temp1.ww; d.buttH _ temp1.wh; d.maxBW _ temp2.ww; Buttons.Destroy[temp1]; Buttons.Destroy[temp2]; END; d.displayProperties[byteLength] _ TRUE; d.displayProperties[createTime] _ TRUE; d.topChild _ CreateSelector[name: "Level:", values: LIST[$User, $FileProperties, $OwnerProperties, $Administrator, $STOP], change: ChangeLevel, clientData: d, viewer: v, x: 2, y: 1].child; d.script _ TypeScript.Create[ info: [parent: v, wh: v.ch - (d.topChild.wy + d.topChild.wh + 2), ww: v.cw, border: FALSE, wy: d.topChild.wy + d.topChild.wh + 2, wx: 0] ]; Containers.ChildXBound[v, d.script]; Containers.ChildYBound[v, d.script]; [in: d.in, out: d.out] _ ViewerIO.CreateViewerStreams[NIL, d.script]; CreateButtons[d, v]; END; ChangeLevel: PROC[parent: ViewerClasses.Viewer, clientData: REF ANY, value: ATOM] = BEGIN d: MyData = NARROW[clientData]; p: ViewerClasses.Viewer = NARROW[parent]; SELECT value FROM $User => d.level _ user; $FileProperties => d.level _ fileProperties; $OwnerProperties => d.level _ ownerProperties; $Administrator => d.level _ administrator; $STOP => { d.stopFlag _ TRUE ; RETURN; }; ENDCASE => { d.out.PutRope["\nNot Implemented\n"]; }; CreateButtons[d, parent] END; CreateButtons: PUBLIC ENTRY PROC[d: MyData, parent: ViewerClasses.Viewer] = BEGIN child: ViewerClasses.Viewer _ NIL; EnquiryButton: PROC[q: MBQueue.Queue, name: Rope.ROPE, proc: Buttons.ButtonProc, width: INTEGER _ d.maxW, guarded: BOOL _ FALSE, doc:Rope.ROPE _ NIL] = BEGIN IF q # NIL THEN child _ q.CreateButton[ info: [name: name, parent: kids, border: TRUE, wy: child.wy, wx: child.wx + width - 1, ww: width], proc: proc, clientData: d, fork: TRUE, paint: FALSE, guarded: guarded, documentation: doc] ELSE child _ Buttons.Create[ info: [name: name, parent: kids, border: TRUE, wy: child.wy, wx: child.wx + width - 1, ww: width], proc: proc, clientData: d, fork: TRUE, paint: FALSE, guarded: guarded, documentation: doc]; END; LabelText: PROC[q: MBQueue.Queue, name, data: Rope.ROPE, prev: ViewerClasses.Viewer, width: INTEGER _ d.maxW, textWidth: INTEGER _ 2*d.maxW, newline: BOOL _ TRUE, textLabelProc: Buttons.ButtonProc _ OtherTextLabelProc] RETURNS[ViewerClasses.Viewer] = BEGIN x: INTEGER = IF newline THEN 2 ELSE child.wx + width + (textWidth) - 1; y: INTEGER = IF newline THEN child.wy + child.wh + 1 ELSE child.wy; child _ ViewerTools.MakeNewTextViewer[ info: [parent: kids, wh: d.buttH, ww: width + (textWidth), scrollable: FALSE, data: IF prev = NIL THEN data ELSE ViewerTools.GetContents[prev], border: FALSE, wx: x + width + 2, wy: y], paint: FALSE ]; [] _ q.CreateButton[ info: [name: name, parent: kids, wh: d.buttH, border: FALSE, wx: x, wy: y], proc: textLabelProc, clientData: child, fork: FALSE, paint: FALSE]; RETURN[child] END; Label: PROC[name: Rope.ROPE] = BEGIN child _ Labels.Create[ info: [name: name, parent: kids, border: FALSE, wy: child.wy + child.wh + (IF child.class.flavor = $Button THEN -1 ELSE 2), wx: 2], paint: FALSE ]; END; Rule: PROC = BEGIN child _ Rules.Create[ info: [parent: kids, border: FALSE, wy: IF child = NIL THEN 0 ELSE child.wy + child.wh + 2, wx: 0, ww: kids.ww, wh: 1], paint: FALSE ]; Containers.ChildXBound[kids, child]; END; userButtons: PROC = BEGIN Label["Command: "]; EnquiryButton[q: d.q, name: "List", proc: ListFilesProc]; EnquiryButton[q: d.q, name: "Delete", proc: DeleteFilesProc, guarded: TRUE, doc: "Delete requires confirmation"]; EnquiryButton[q: d.q, name: "Copy", proc: CopyFilesProc]; EnquiryButton[q: d.q, name: "FullCopy", proc: FullCopyFilesProc]; EnquiryButton[q: d.q, name: "Options", proc: OptionsProc]; IF d.displayOptions THEN BEGIN buttonCount: INTEGER _ 0 ; count: INT; option: AlpineEnvironment.Property; propertyName: ROPE ; Rule[]; Label["Option: "]; FOR count IN [0..NumberOfAlpineProperties) DO [option, propertyName] _ PropertySetToRopeArray[count]; IF (buttonCount >= 4) THEN BEGIN Label[""]; buttonCount _ 0 ; END; buttonCount _ buttonCount + 1 ; EnquiryButton[q: NIL, name: propertyName, proc: ChangeOptionsProc, width: d.maxBW]; IF d.displayProperties[option] THEN BEGIN Buttons.SetDisplayStyle[child, $WhiteOnBlack]; END; ENDLOOP; END; END; filePropertiesButtons: PROC = BEGIN Label["Function: "]; EnquiryButton[q: d.q, name: "Examine", proc: ExamineProc]; EnquiryButton[q: d.q, name: "Apply", proc: ApplyProc, guarded: TRUE, doc: "Apply requires confirmation; single file application only"]; Rule[]; d.oStringName _ LabelText[ q: d.q, name: "stringName:", data: "", prev: d.oStringName, width: d.maxBW, textWidth: 5*d.maxW]; d.oByteLength _ LabelText[ q: d.q, name: "byteLength:", data: "", prev: d.oByteLength, width: d.maxBW ]; d.oSize _ LabelText[ q: d.q, name: "size:", data: "", prev: d.oSize, width: d.maxBW, newline: FALSE ]; d.oHighWaterMark _ LabelText[ q: d.q, name: "highWaterMark:", data: "", prev: d.oHighWaterMark, width: d.maxBW ]; d.oOwner _ LabelText[ q: d.q, name: "owner:", data: "", prev: d.oOwner, width: d.maxBW, newline: FALSE ]; d.oReadAccess _ LabelText[ q: d.q, name: "readAccess:", data: "", prev: d.oReadAccess, width: d.maxBW, textWidth: 5*d.maxW]; d.oModifyAccess _ LabelText[ q: d.q, name: "modifyAccess:", data: "", prev: d.oModifyAccess, width: d.maxBW, textWidth: 5*d.maxW]; END; ownerPropertiesButtons: PROC = BEGIN Label["Function: "]; EnquiryButton[q: d.q, name: "Quota", proc: QuotaProc]; EnquiryButton[q: d.q, name: "Get", proc: GetOwnerPropertiesProc]; EnquiryButton[q: d.q, name: "Put", proc: PutOwnerPropertiesProc, guarded: TRUE, doc: "Put owner properties requires confirmation"]; Rule[]; d.oCreateAccessList _ LabelText[ q: d.q, name: "createAccess:", data: "", prev: d.oCreateAccessList, width: 2*d.maxW, textWidth: 5*d.maxW]; d.oRootReadAccess _ LabelText[ q: d.q, name: "root readAccess:", data: "", prev: d.oRootReadAccess, width: 2*d.maxW, textWidth: 5*d.maxW]; d.oRootModifyAccess _ LabelText[ q: d.q, name: "root modifyAccess:", data: "", prev: d.oRootModifyAccess, width: 2*d.maxW, textWidth: 5*d.maxW]; END; administratorButtons: PROC = { Label["Command: "]; EnquiryButton[q: d.q, name: "CreateOwner", proc: CreateOwnerProc, width: d.maxBW, guarded: TRUE, doc: "Create requires confirmation"]; EnquiryButton[q: d.q, name: "DestroyOwner", proc: DestroyOwnerProc, width: d.maxBW, guarded: TRUE, doc: "Destroy requires confirmation"]; EnquiryButton[q: d.q, name: "WriteQuota", proc: WriteQuotaProc, width: d.maxBW, guarded: TRUE, doc: "Write Quota requires confirmation"]; EnquiryButton[q: d.q, name: "ListOwners", proc: ListOwnersProc, width: d.maxBW]; EnquiryButton[q: d.q, name: "ReadStatistics", proc: ReadDBPropertiesProc, width: d.maxBW]; Rule[]; d.oQuota _ LabelText[ q: d.q, name: "quota:", data: "", prev: d.oQuota, width: d.maxBW, textWidth: 5*d.maxW]; Rule[]; Label["Option: "]; EnquiryButton[q: NIL, name: "Assert Wheel", proc: ChangeAssertWheel, width: d.maxBW]; IF d.assertWheel THEN BEGIN Buttons.SetDisplayStyle[child, $WhiteOnBlack]; END; EnquiryButton[q: NIL, name: "Break Locks", proc: ChangeBreakLocks, width: d.maxBW]; IF d.breakLocks THEN { Buttons.SetDisplayStyle[child, $WhiteOnBlack]; }; }; kids: ViewerClasses.Viewer = Containers.Create[ info: [parent: parent, border: FALSE, scrollable: FALSE, wx: 0, wy: -9999, ww: 9999, wh: 0] ]; userName, userPassword: ROPE; Containers.ChildXBound[parent, kids]; Rule[]; [userName, userPassword] _ UserCredentials.Get[]; d.user _ LabelText[ q: d.q, name: "User:", data: userName, prev: d.user ]; d.password _ LabelText[ q: d.q, name: "Password:", data: "", prev: d.password, newline: FALSE ]; d.srcServer _ LabelText[ q: d.q, name: "Src Server:", data: "Luther.alpine", prev: d.srcServer, textLabelProc: ServerTextLabelProc ]; IF d.level = user THEN { d.destServer _ LabelText[ q: d.q, name: "Dest Server:", data: "", prev: d.destServer, newline: FALSE, textLabelProc: ServerTextLabelProc ]; } ELSE d.destServer _ NIL ; d.srcFile _ LabelText[ q: d.q, name: "Src File:", data: "", prev: d.srcFile ]; IF d.level = user THEN { d.destFile _ LabelText[ q: d.q, name: "Dest File:", data: "", prev: d.destFile, newline: FALSE ] } ELSE d.destFile _ NIL ; IF d.level = user THEN userButtons[]; IF d.level = fileProperties THEN filePropertiesButtons[] ELSE { d.oStringName _ d.oByteLength _ d.oHighWaterMark _ d.oSize _ d.oReadAccess _ d.oModifyAccess _ d.oOwner _ NIL; } ; IF d.level = ownerProperties THEN ownerPropertiesButtons[] ELSE { d.oCreateAccessList _ NIL ; d.oRootReadAccess _ NIL ; d.oRootModifyAccess _ NIL ; }; IF d.level = administrator THEN administratorButtons[] ELSE d.oQuota _ NIL; Rule[]; BEGIN kidsY: INTEGER = d.topChild.wy + d.topChild.wh + 2; kidsH: INTEGER = child.wy + child.wh + 2; IF d.kids # NIL THEN ViewerOps.DestroyViewer[d.kids, FALSE]; d.kids _ kids; ViewerOps.MoveViewer[viewer: d.script, x: 0, y: kidsY + kidsH, w: d.script.ww, h: parent.ch - (kids.wy + kidsH), paint: FALSE]; ViewerOps.SetOpenHeight[parent, kidsY + kidsH + 8 * d.buttH]; IF NOT parent.iconic THEN ViewerOps.ComputeColumn[parent.column]; ViewerOps.MoveViewer[viewer: kids, x: kids.wx, y: kidsY, w: kids.ww, h: kidsH]; END; END; ServerTextLabelProc: Buttons.ButtonProc = BEGIN text: ViewerClasses.Viewer = NARROW[clientData]; SELECT mouseButton FROM red => { IF ViewerTools.GetSelectedViewer[] = text THEN { NextName: PROC [this: ROPE, list: LIST OF ROPE] RETURNS [next: ROPE _ NIL] = { IF list = NIL THEN RETURN; FOR l: LIST OF ROPE _ list, l.rest UNTIL l = NIL DO IF this.Equal[l.first, FALSE] THEN RETURN[IF l.rest = NIL THEN list.first ELSE l.rest.first] ENDLOOP; RETURN[list.first] }; contents: ROPE _ ViewerTools.GetContents[text]; ViewerTools.SetContents[text, contents _ NextName[contents, NamePrefixes]]; }; ViewerTools.SetSelection[text, NIL]; }; blue => { ViewerTools.SetContents[text, NIL]; ViewerTools.SetSelection[text, NIL] }; yellow => NULL; ENDCASE => ERROR; END; OtherTextLabelProc: Buttons.ButtonProc = BEGIN text: ViewerClasses.Viewer = NARROW[clientData]; SELECT mouseButton FROM red => ViewerTools.SetSelection[text, NIL]; blue => { ViewerTools.SetContents[text, NIL]; ViewerTools.SetSelection[text, NIL] }; yellow => NULL; ENDCASE => ERROR; END; Selector: TYPE = REF SelectorRec; SelectorRec: TYPE = RECORD[ value: REF ATOM, change: PROC[parent: ViewerClasses.Viewer, clientData: REF ANY, value: ATOM], clientData: REF ANY, buttons: LIST OF Buttons.Button, values: LIST OF ATOM ]; CreateSelector: PROC[name: Rope.ROPE, values: LIST OF ATOM, init: REF ATOM _ NIL, change: PROC[parent: ViewerClasses.Viewer, clientData: REF ANY, value: ATOM] _ NIL, clientData: MyData, viewer: ViewerClasses.Viewer, x, y: INTEGER] RETURNS[child: ViewerClasses.Viewer, value: REF ATOM] = BEGIN selector: Selector _ NEW[ SelectorRec _ [value: IF init # NIL THEN init ELSE NEW[ATOM_values.first], change: change, clientData: clientData, buttons: NIL, values: values ] ]; last: LIST OF Buttons.Button _ NIL; value _ selector.value; child _ Labels.Create[info: [name: name, parent: viewer, border: FALSE, wx: x, wy: y] ]; FOR a: LIST OF ATOM _ values, a.rest UNTIL a = NIL DO IF a.first = $STOP THEN child _ Buttons.Create[ info: [name: Atom.GetPName[a.first], parent: viewer, border: TRUE, wy: child.wy, wx: child.wx + child.ww + 2], proc: SelectorProc, clientData: selector, fork: TRUE, paint: TRUE] ELSE child _ clientData.q.CreateButton[ info: [name: Atom.GetPName[a.first], parent: viewer, border: TRUE, wy: child.wy, wx: child.wx + child.ww + 2], proc: SelectorProc, clientData: selector, fork: TRUE, paint: TRUE]; IF last = NIL THEN last _ selector.buttons _ CONS[first: child, rest: NIL] ELSE { last.rest _ CONS[first: child, rest: NIL]; last _ last.rest }; IF a.first = selector.value^ THEN Buttons.SetDisplayStyle[child, $WhiteOnBlack]; ENDLOOP; END; SelectorProc: Buttons.ButtonProc = BEGIN self: Buttons.Button = NARROW[parent]; selector: Selector = NARROW[clientData]; buttons: LIST OF Buttons.Button _ selector.buttons; changeHighlight: BOOL = NOT Rope.Equal[self.name,"STOP"]; FOR a: LIST OF ATOM _ selector.values, a.rest UNTIL a = NIL DO IF self = buttons.first THEN BEGIN selector.value^ _ a.first; IF selector.change # NIL THEN selector.change[self.parent, selector.clientData, a.first]; IF changeHighlight THEN Buttons.SetDisplayStyle[buttons.first, $WhiteOnBlack]; END ELSE IF changeHighlight THEN Buttons.SetDisplayStyle[buttons.first, $BlackOnWhite]; buttons _ buttons.rest; ENDLOOP; END; Commander.Register[key: "Yodel", proc: Create, doc: "Performs Chat-like functions for Alpine File Servers"]; END. Ê-- YodelRoot.mesa -- Yodel: Button-style interface -- Last Edited by: Hagmann, January 23, 1985 3:48:55 pm PST Rhagmann, January 24, 1985 8:18:07 am PST ******** Enquiry operations ******** -- [exec: ExecHandle, clientData: REF ANY _ NIL] RETURNS[ok: BOOLEAN _ TRUE] this is the container that includes all the other containers kludge to find max button sizes! -- start displaying only these two properties build viewer for "Level" menu create type script; it will be bound at the end of CreateButtons under all the menus build an image from the data in parameter d start of body of CreateButtons put up user/password on a line ask for source and destination servers ask for source and destination filenames parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL Êf˜Jšœ™Jšœ!™!šœ;™;J™)—JšœÏk ˜ J˜Jšœœ ˜$Jšœ œ˜!Jšœœ ˜Jšœ œ9˜HJšœ œ˜*Jšœ œ%˜6Jšœ˜Jšœ œ ˜Jšœ œ ˜.Jšœ˜Jšœ œ ˜Jšœ œ ˜Jšœœ˜Jšœœ ˜Jšœ œ˜(Jšœ œ<˜LJšœ œ!˜3Jšœ4˜4Jšœ ˜ J˜Jš Ïb œœœœœ ˜0J˜Jšœ'œh˜˜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šœI™IJš˜Jšœœ˜!Jšœ<™Jšœ˜Jšœœœ œ˜=Jšœ+˜+Jšœ9œ˜?Jšœ˜Jšœœœ œ˜=Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœœ˜—Jšœ*™*Jšœ$œ˜)Jšœ$œ˜)Jšœ™Jšœ-˜-Jšœ œB˜RJšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ@™@Jšœ™Jšœ˜JšœS˜SJšœœ˜Jšœ?˜?Jšœ˜Jšœ&˜&Jšœ&˜&Jšœ˜Jšœ8œ ˜GJšœ˜Jšœ˜—J˜J˜š Ïn œœ+œœ œ˜Sš˜Jšœ œ ˜Jšœœ ˜)šœ˜Jšœ˜Jšœ,˜,Jšœ.˜.Jšœ*˜*šœ ˜ Jšœ œ˜Jšœ˜Jšœ˜—šœ˜ Jšœ%˜%Jšœ˜——Jšœ˜Jšœ˜—Jšœ+™+—šŸ œœœœ+˜KJšœ˜Jšœ œ˜$Jšœ˜šŸ œœœ#œ ˜iJš œ œœ œœ˜0Jšœ˜ Jšœ+˜+Jšœ1œ˜6JšœB˜BJšœ˜Jšœ˜Jšœœ˜Jšœœ˜Jšœ˜Jšœ˜—Jšœ$˜$Jšœ1œ˜6JšœB˜BJšœ˜Jšœ˜Jšœœ˜Jšœœ˜Jšœ˜šœ˜Jšœœ˜—Jšœ˜šŸ œœ$œ˜TJš œ œœœœ˜PJšœ:˜:Jšœœ˜%Jšœ˜ Jš œœœ œœ$˜KJš œœœ œœ ˜GJšœ*˜*JšœNœ˜TJš œœœœœ˜OJšœœ˜Jšœ(˜(Jšœœ˜Jšœ˜Jšœ7˜7Jšœœ˜.Jšœ8œ œ˜MJšœœ˜Jšœœ˜—Jšœ˜Jšœ˜šŸœœ œ˜Jšœ˜ Jšœ˜Jšœ/œ˜5Jšœ(œœœ˜XJšœ˜Jšœ œ˜Jšœœ˜Jšœ˜—šŸœœ˜ Jšœ˜ Jšœ˜Jšœ#œ˜)Jš œœ œœœ5˜`Jšœ œ˜Jšœ(˜(Jšœœ˜Jšœ˜—šœ œ˜Jšœ˜Jšœ9˜9JšœFœ'˜qJšœ9˜9JšœA˜AJšœ:˜:J˜šœœ˜Jšœ œ˜Jšœœ˜ Jšœ#˜#Jšœœ˜Jšœ˜Jšœ˜šœœ ˜.Jšœ7˜7šœœ˜ Jšœ ˜ Jšœ˜Jšœ˜—Jšœ˜Jšœœ?˜Sšœœ˜)Jšœ.˜.Jšœ˜—Jšœ˜—Jšœ˜—Jšœ˜—Jšœ˜Jšœ˜šžœ œ˜Jšœ˜Jšœ˜Jšœ>˜>JšœCœ˜HJšœG˜GJšœ˜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šœ˜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šœE˜EJšœNœ˜SJšœ8˜8Jšœ˜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šœ[œ'˜†Jšœ]œ(˜‰JšœYœ,˜‰JšœP˜PJšœZ˜ZJšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ$˜$Jšœ˜Jšœ˜JšœœA˜Ušœœ˜Jšœ.˜.Jšœ˜—Jšœœ?˜Sšœœ˜Jšœ.˜.Jšœ˜—Jšœ˜—Jšœ˜Jšœ1˜1Jšœ$œœ'˜cJšœœ˜Jšœ˜Jšœ™Jšœ'˜'Jšœ ˜ Jšœ™Jšœ3˜3Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ ˜ Jšœœ˜ Jšœ˜Jšœ&™&Jšœ˜Jšœ˜Jšœ#˜#Jšœ%˜%Jšœ!˜!Jšœ4˜4Jšœœœ˜Jšœ˜Jšœ˜Jšœ$˜$Jšœ˜Jšœ"˜"Jšœœ˜Jšœ4˜4Jšœ˜Jšœœœ˜Jšœ(™(Jšœ˜Jšœ˜Jšœ!˜!Jšœ˜Jšœ!˜!Jšœœœ˜Jšœ˜Jšœ˜Jšœ"˜"Jšœ˜Jšœ ˜ Jšœœ˜Jšœ˜Jšœœœ˜Jšœ˜Jšœœ˜%šœœœ˜?Jšœjœ˜nJšœ˜—šœœœ˜AJšœœ˜Jšœœ˜Jšœœ˜J˜—Jšœœœ œ˜KJšœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ œ%˜9Jšœ œ˜/Jš œœ œœ!œ˜BJšœ˜JšœT˜TJšœ+˜+Jšœœ˜JšœC˜CJšœœœœ(˜GJšœU˜UJšœœ˜Jšœœ˜Jšœ˜—šžœ˜)JšœT™TJšœ˜Jšœœ ˜2Jšœœ ˜Jšœ ˜ Jšœœ(œ˜5JšœŸœœœœœœœœœ˜TJš œœœœœ˜!Jšœœœœœœœ˜:Jšœœœœœœ œœ ˜VJšœ˜Jšœœ˜Jšœœ ˜Jšœ ˜ Jšœœ!˜5JšœA˜AJšœ˜Jšœ˜Jšœ ˜ Jšœ$œ˜)Jšœ˜Jšœ,œ"œ˜XJšœœ˜Jšœœœ˜Jšœœ˜Jšœ˜—šžœ˜(JšœT™TJšœ˜Jšœœ ˜2Jšœœ ˜Jšœ*œ˜/Jšœ,œ"œ˜XJšœœ˜Jšœœœ˜Jšœœ˜Jšœ˜Jšœ œœ ˜!Jšœœœ˜Jšœ œœ˜Jš œ œ+œœ œ˜OJšœœœ˜Jšœ œœ˜"Jšœ œœœ˜JšœŸœœ œ˜&Jšœœœœ˜*Jšœœœœ˜*Jš œœ+œœ!œœ˜€Jšœ(˜(Jšœ2˜2Jšœœ˜#Jšœ œ%œœ˜DJšœ˜Jšœœ˜)Jš œ œœœœœœ˜@Jšœ˜Jšœ˜Jšœœ˜Jšœ˜Jšœœœœ˜%Jšœ˜JšœCœ˜ZJš œœœœœœ˜4Jšœ˜Jšœœœ]œ˜~Jšœ:˜:Jšœ˜Jšœ˜Jšœœ˜Jšœœ˜Jšœœ#˜-JšœEœ˜JJšœ:˜:Jšœ˜Jšœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœœœ˜AJšœœœœ˜JJšœœœ/˜UJšœœ˜ Jšœœ˜—J˜šž œ˜"JšœT™TJšœ˜Jšœœ ˜(Jšœœ ˜*Jšœ œœ#˜5Jšœœœ˜;Jš œœœœœœ˜=Jšœœœ˜Jšœœ˜Jšœ$˜$Jšœ œœœ<˜cJšœ œœ7˜XJšœ ˜ Jšœœœœ7˜XJšœ˜Jšœœ˜ Jšœœ˜Jšœ˜Jšœ.˜.JšœE˜EJšœœ˜J˜J˜—J˜—…—Bà[