DIRECTORY Atom USING [PutPropOnList], CD USING [Design, Layer, LayerKey, Number, Position, Rect, undefLayer], CDBasics USING [SizeOfRect], CDCommandOps USING [DoWithResource], CDIO USING [ReadDesign], CDLayers USING [CurrentLayer], CDOps USING [BoundingBox], CDPanel USING [Button, Info, Line, Text, TakeDownText], CDProperties USING [PutDesignProp, RegisterProperty], CDSequencer USING [Command, ImplementCommand, UseAbortFlag], CDValue USING [RegisterKey, Store], CDViewer USING [ViewerList, ViewersOf, VisibleRect], Commander USING [CommandProc, Handle, Register], CommandTool USING [NextArgument], Convert USING [IntFromRope, Error], CStitching USING [NewTesselation, Tesselation, FindTile], FS USING [ComponentPositions, Error, ExpandName, FileInfo], FSExtras USING [GetWDir], Imager USING [metersPerPoint, Rectangle], IO USING [atom, card, GetBool, GetInt, GetReal, int, PutF, PutFR, real, RIS, rope], MessageWindow USING [Append, Blink, Clear], Nectarine USING [DoInterpress, invalidPrinter, Print], NectarinePd USING [field], PrintingP4V3, Process USING [Detach], Real USING [Fix, Float, Round], Rope USING [ActionType, Cat, Concat, Equal, IsEmpty, Map, ROPE, Substr], RopeFile USING [Create], RuntimeError USING [UNCAUGHT], SafeStorage USING [GetCanonicalReferentType, Type], SweepCollectableStorage USING [EnumerateCollectableStorage, InfoProc], TEditDocument USING [Selection], TEditInputOps USING [Break, CallWithLocks], TerminalIO USING [PutF, PutRope], TextNode USING [Ref], TiogaAccess USING [Create, GetInternalProp, Put, TiogaChar, Writer, WriteSelection, WriteViewer], UserProfile USING [Boolean, Token], VFonts USING [StringWidth], ViewerClasses USING [Viewer], ViewerOps USING [BlinkDisplay, BlinkIcon, CreateViewer], XNSPrint USING [Error, FormatterStatus, GetPaperDimensions, GetPrinterStatus, MarkingEngineStatus, PaperDimensions, PrinterStatus, SpoolerStatus]; NectarineCommand: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCommandOps, CDIO, CDLayers, CDOps, CDPanel, CDProperties, CDSequencer, CDValue, CDViewer, Commander, CommandTool, Convert, CStitching, FS, FSExtras, IO, MessageWindow, Nectarine, NectarinePd, Process, Real, Rope, RopeFile, RuntimeError, SafeStorage, SweepCollectableStorage, TEditInputOps, TerminalIO, TiogaAccess, UserProfile, VFonts, ViewerOps, XNSPrint ~ BEGIN OPEN Real; masterKey: ATOM ~ $Nectarine; whatKey: ATOM ~ $NectarineWhat; whereKey: ATOM ~ $NectarineWhere; copiesKey: ATOM ~ $NectarineCopies; scaleKey: ATOM ~ $NectarineScale; monoLayerKey: ATOM ~ $NectarineMonoLayer; CSTile: SafeStorage.Type; ROPE: TYPE ~ Rope.ROPE; lastPrint: RECORD [ip: ROPE, key: ATOM, q: INT, l, r: BOOL, w: Imager.Rectangle]; maxHoldedArea: REF Imager.Rectangle _ NIL; NectarineCommand: PROC [comm: CDSequencer.Command] ~ BEGIN abort: REF BOOL _ NEW [BOOL _ FALSE]; DoIt: PROC [comm: CDSequencer.Command] ~ BEGIN what: ROPE ~ CDPanel.TakeDownText [comm.design, whatKey]; where: ROPE ~ CDPanel.TakeDownText [comm.design, whereKey]; howMany: INT _ 0; -- number of copies scale: REAL _ 0.0; -- lambda in millimetres monoLayer: BOOL _ FALSE; -- only the layer of interset will be printed layerOfInterest: CD.Layer _ CD.undefLayer; cropKey, printKey: ATOM; masterName: ROPE _ NIL; usedField: Imager.Rectangle; rollPaperDeviceHint: REF Imager.Rectangle _ NIL; isPagePrinter: BOOL; IF where.Equal ["Explain", FALSE] THEN {ExplainGoals []; RETURN}; SELECT TRUE FROM what.Equal ["Design", FALSE] => cropKey _ $NectarineAll; what.Equal ["Wysiwyg", FALSE] => cropKey _ $NectarineWysiwyg; what.Equal ["Selection", FALSE] => cropKey _ $NectarineSel; ENDCASE => BEGIN TerminalIO.PutRope ["Unknown cropping option.\n"]; ERROR ABORTED END; SELECT TRUE FROM where.Equal ["ColorVersatec", FALSE] => BEGIN printKey _ $NColorVersatec END; where.Equal ["Color400", FALSE] => printKey _ $NColor400; where.Equal ["Raven300", FALSE] => printKey _ $NRaven300; where.Equal ["Raven384", FALSE] => printKey _ $NRaven384; where.Equal ["C2700", FALSE] => printKey _ $C2700; where.Equal ["Bw400", FALSE] => printKey _ $NBw400; where.Equal ["Versatec", FALSE] => printKey _ $NVersatec; where.Equal ["Erie", FALSE] => printKey _ $NPlateMaker; where.Equal ["Tioga doc", FALSE] => printKey _ $NPasteInTioga; where.Equal ["IP only", FALSE] => printKey _ $NmasterOnly; where.Equal ["hold", FALSE] => printKey _ $Nhold; where.Equal ["PeachExpand", FALSE] => BEGIN TerminalIO.PutRope ["I will create an Interpress master, which I will use to produce a PD file. I will then send it to the expansion server to create a bitmap, and from there I will send it to the color Versatec. You will have to delete the temporary files manually.\n"]; printKey _ $NPeachExpand END; ENDCASE => {TerminalIO.PutRope ["Unknown printer.\n"]; ERROR ABORTED}; isPagePrinter _ (printKey = $NRaven300) OR (printKey = $NRaven384) OR (printKey = $NmasterOnly) OR (printKey = $NPlateMaker) OR (printKey = $NColor400) OR (printKey = $NBw400) OR (printKey = $C2700); BEGIN r: ROPE ~ CDPanel.TakeDownText [comm.design, copiesKey]; IF r.IsEmpty THEN howMany _ 1 ELSE howMany _ IO.GetInt [IO.RIS [r] ! RuntimeError.UNCAUGHT => {howMany _ 1; CONTINUE}] END; BEGIN r: ROPE ~ CDPanel.TakeDownText [comm.design, scaleKey]; IF r.IsEmpty THEN scale _ 0.0 ELSE scale _ IO.GetReal [IO.RIS [r] ! RuntimeError.UNCAUGHT => {scale _ 0.0; CONTINUE}]; IF (scale # 0.0) THEN TerminalIO.PutF ["Fixed scale  = %g mm.\n", IO.real [scale]] ELSE TerminalIO.PutRope ["Will scale to fit page.\n"] END; BEGIN r: ROPE ~ CDPanel.TakeDownText [comm.design, monoLayerKey]; IF r.IsEmpty THEN monoLayer _ FALSE ELSE monoLayer _ IO.GetBool [IO.RIS [r] ! RuntimeError.UNCAUGHT => {monoLayer _ FALSE; CONTINUE}]; IF monoLayer THEN BEGIN layerOfInterest _ CDLayers.CurrentLayer [comm.design]; TerminalIO.PutF ["Will print only the current layer (%g).\n", IO.atom [CD.LayerKey [layerOfInterest]]] END END; IF (masterName.IsEmpty []) THEN BEGIN cW: CD.Rect; -- ChipNDale window l: CD.Number ~ comm.design.technology.lambda; SELECT cropKey FROM $NectarineAll => cW _ CDOps.BoundingBox [comm.design]; $NectarineSel => BEGIN size: CD.Position; cW _ CDOps.BoundingBox [comm.design, TRUE]; size _ CDBasics.SizeOfRect [cW]; IF (size.x <= 0) OR (size.y <= 0) THEN BEGIN TerminalIO.PutRope ["You do not have a selection in this design !\n"]; ERROR ABORTED END END; $NectarineWysiwyg => BEGIN viewers: CDViewer.ViewerList = CDViewer.ViewersOf [comm.design]; goodViewer: ViewerClasses.Viewer; good: INT _ 0; IF (viewers = NIL) THEN BEGIN TerminalIO.PutRope ["You do not see anything of this design !\n"]; ERROR ABORTED END; FOR v: CDViewer.ViewerList _ viewers, v.rest WHILE v # NIL DO IF NOT v.first.iconic THEN {goodViewer _ v.first; good _ good.SUCC} ENDLOOP; SELECT good FROM 0 => {TerminalIO.PutRope ["You do not see anything !\n"]; ERROR ABORTED}; > 1 => TerminalIO.PutRope ["WARNING: you see more than one viewer. I pick one at random\n"]; ENDCASE => NULL; cW _ CDViewer.VisibleRect [goodViewer] END; ENDCASE => ERROR; cW _ [x1: cW.x1 - l, x2: cW.x2 + l, y1: cW.y1 - l, y2: cW.y2 + l]; IF (scale # 0.0) AND isPagePrinter THEN BEGIN currentWindow: CD.Rect; medium: Imager.Rectangle ~ [x: 0.0, y: 0.0, w: 215.9, h: 279.4]; -- in mm field: Imager.Rectangle ~ NectarinePd.field; -- in mm windowW: CD.Number ~ Round [field.w / scale] * l; -- in cd units windowH: CD.Number ~ Round [field.h / scale] * l; -- in cd units totalWidth: REAL ~ Float [cW.x2 - cW.x1] / l * scale; -- in mm totalHeight: REAL ~ Float [cW.y2 - cW.y1] / l * scale; -- in mm columns: INTEGER _ Fix [totalWidth / field.w]; -- Fix truncates rows: INTEGER _ Fix [totalHeight / field.h]; -- Fix truncates IF (cW.x1 + windowW * columns < cW.x2) THEN columns _ columns.SUCC; IF (cW.y1 + windowH * rows < cW.y2) THEN rows _ rows.SUCC; TerminalIO.PutF ["Nectarine will break the design in %g A pages.\n", IO.int [columns*rows]]; currentWindow _ [x1 ~ cW.x1, y1 ~ cW.y2 - windowH, x2 ~ cW.x1 + windowW, y2 ~ cW.y2]; FOR i: INTEGER IN [0 .. rows) DO FOR j: INTEGER IN [0 .. columns) DO masterName _ Nectarine.DoInterpress [design: comm.design, chipNDaleWindow: currentWindow, clip: TRUE, onlySel: (cropKey = $NectarineSel), layer: layerOfInterest, singleLayer: monoLayer, register: (printKey = $NPlateMaker), lambda: scale, firstPage: ((i = 0) AND (j = 0)) OR ((printKey = $Nhold) AND (maxHoldedArea = NIL)), lastPage: ((i = rows - 1) AND (j = columns - 1) AND (printKey # $Nhold)), abortFlag: abort].masterName; currentWindow.x1 _ currentWindow.x2; currentWindow.x2 _ currentWindow.x2 + windowW ENDLOOP; currentWindow.x1 _ cW.x1; currentWindow.x2 _ cW.x1 + windowW; currentWindow.y2 _ currentWindow.y1; currentWindow.y1 _ currentWindow.y1 - windowH ENDLOOP; usedField _ [x: 0, y: 0, w: 0, h: -1] -- w > h END ELSE [masterName, usedField] _ Nectarine.DoInterpress [design: comm.design, chipNDaleWindow: cW, clip: (cropKey = $NectarineWysiwyg) OR (cropKey = $NectarineSel), onlySel: (cropKey = $NectarineSel), layer: layerOfInterest, singleLayer: monoLayer, lambda: scale, firstPage: (maxHoldedArea = NIL), lastPage: (printKey # $Nhold), register: (printKey = $NPlateMaker), abortFlag: abort]; IF (printKey = $Nhold) THEN BEGIN IF (maxHoldedArea = NIL) THEN maxHoldedArea _ NEW [Imager.Rectangle _ usedField] ELSE BEGIN x1: REAL ~ MAX [maxHoldedArea.x + maxHoldedArea.w, usedField.x + usedField.w]; y1: REAL ~ MAX [maxHoldedArea.y + maxHoldedArea.h, usedField.y + usedField.h]; maxHoldedArea.x _ MIN [maxHoldedArea.x, usedField.x]; maxHoldedArea.y _ MIN [maxHoldedArea.y, usedField.y]; maxHoldedArea.w _ x1 - maxHoldedArea.x; maxHoldedArea.h _ y1 - maxHoldedArea.y END END ELSE BEGIN IF (maxHoldedArea # NIL) THEN {usedField _ maxHoldedArea^; maxHoldedArea _ NIL} END; CDProperties.PutDesignProp [comm.design, masterKey, masterName] END; -- create Interpress master lastPrint _ [ip: masterName, key: printKey, q: howMany, l: (scale # 0.0), r: (printKey = $NPlateMaker), w: usedField]; -- for Redo SELECT printKey FROM $NmasterOnly => NULL; $NPasteInTioga => Paste [masterName, usedField]; $Nhold => TerminalIO.PutRope ["Nectarine is holding the result in a buffer until `where' no longer is `hold'.\n"]; ENDCASE => BEGIN rollPaperDeviceHint _ NEW [Imager.Rectangle _ usedField]; [] _ Nectarine.Print [masterName: masterName, printerKey: printKey, copies: howMany, doNotScale: (scale # 0.0), mergeRegister: FALSE, sizeHint: rollPaperDeviceHint, abortFlag: abort ! Nectarine.invalidPrinter => ERROR] END; TerminalIO.PutRope ["Design unlocked by Nectarine.\n"] END; -- DoIt CDSequencer.UseAbortFlag [comm.design, abort]; [] _ CDCommandOps.DoWithResource [DoIt, comm, $Nectarine] END; -- NectarineCommand Paste: PROC [name: ROPE, bb: Imager.Rectangle, newViewer: BOOL _ FALSE] ~ BEGIN master: ROPE ~ RopeFile.Create [name]; -- the Interpress master desguised as a rope document: TiogaAccess.Writer _ TiogaAccess.Create []; -- a working area Tioga doc vanillaChar: TiogaAccess.TiogaChar ~ [0, 0C, ALL [FALSE], NIL, TRUE, FALSE, 0, NIL]; dummy, ip, caption, rule: TiogaAccess.TiogaChar _ vanillaChar; space: REAL ~ 8.0 * Imager.metersPerPoint * 1000.0; -- in mm topCalcRope: ROPE; -- for postfix property calculating top leading and ident cslPublicationStyle: BOOL ~ UserProfile.Boolean ["Nectarine.CSLPublicationStyle", TRUE]; PutRope: PROC [r: ROPE, attr: TiogaAccess.TiogaChar] ~ BEGIN PutChar: Rope.ActionType ~ {attr.char _ c; document.Put [attr]}; [] _ Rope.Map [base: r, action: PutChar] END; -- PutRope PutProp: PROC [char: TiogaAccess.TiogaChar, prop: ATOM, val: ROPE] RETURNS [TiogaAccess.TiogaChar] ~ BEGIN char.propList _ Atom.PutPropOnList [propList: char.propList, prop: prop, val: TiogaAccess.GetInternalProp [prop, val]]; RETURN [char] END; -- PutProp Stuff: PROC [root: TextNode.Ref, tSel:TEditDocument.Selection] ~ BEGIN IF newViewer THEN BEGIN repository: ViewerClasses.Viewer _ ViewerOps.CreateViewer [$Text]; document.WriteViewer [repository]; ViewerOps.BlinkIcon [repository, 0] END ELSE {TEditInputOps.Break []; TiogaAccess.WriteSelection [document]} END; -- Stuff dummy.endOfNode _ TRUE; PutRope ["\n", dummy]; IF cslPublicationStyle THEN BEGIN dummy.endOfNode _ FALSE; dummy.looks['z] _ TRUE; PutRope ["----------", dummy]; dummy.looks['z] _ FALSE; rule.endOfNode _ TRUE; rule.format _ $unleaded; rule _ PutProp [rule, $ArtworkClass, "Rule"]; rule _ PutProp [rule, $Artwork, "Rule"]; document.Put [rule] END; dummy.endOfNode _ FALSE; dummy.looks['n] _ TRUE; dummy.looks['x] _ TRUE; IF cslPublicationStyle THEN PutRope ["[ Nectarine figure; type 'Artwork on' to a CommandTool ]", dummy] ELSE PutRope ["[ Nectarine, fuzzless and sweeter than peaches ]", dummy]; dummy.looks['n] _ FALSE; dummy.looks['x] _ FALSE; ip.char _ '\n; ip.endOfNode _ TRUE; ip.format _ $artworkFigure; -- it is an artwork node topCalcRope _ IO.PutFR ["%g the lineLength .mul %g .add", IO.real [bb.h/bb.w], IO.real [space]]; IF cslPublicationStyle THEN ip _ PutProp [ip, $Postfix, IO.PutFR ["%g topLeading %g topIndent %g mm bottomLeading 0.0 0.2 0.90 backgroundColor the topLeading 6 pt .sub backgroundAscent 1 pt backgroundDescent 2 pt outlineBoxThickness 1 pt outlineBoxBearoff", IO.rope [topCalcRope], IO.rope [topCalcRope], IO.real [space/2.0]]] -- margin in the document ELSE ip _ PutProp [ip, $Postfix, IO.PutFR ["%g topLeading %g topIndent %g mm bottomLeading", IO.rope [topCalcRope], IO.rope [topCalcRope], IO.real [space/2.0]]]; ip _ PutProp [ip, $Bounds, IO.PutFR ["%g mm xmin %g mm ymin %g mm xmax %g mm ymax", IO.real [bb.x], IO.real [bb.y], IO.real [bb.x+bb.w], IO.real [bb.y+bb.h]]]; -- set the bounding box ip _ PutProp [ip, $Artwork, "Interpress"]; -- the artwork type is "Interpress" ip _ PutProp [ip, $Interpress, master]; -- the Interpress master desguised as a rope ip _ PutProp [ip, $Fit, "TRUE"]; -- fit the figure to the margins of the sibling node document.Put [ip]; IF cslPublicationStyle THEN BEGIN dummy.looks['t] _ TRUE; dummy.char _ '; document.Put [dummy]; PutRope ["Figure 1. [This node is in the format $artworkCaption; if you are using the CedarACMNoReduction style, change the format of this node to $caption, and change the two rules' format to $horizontalrule.]", caption]; dummy.char _ '; document.Put [dummy]; caption.format _ $artworkCaption; caption.char _ 0C; caption.endOfNode _ TRUE; document.Put [caption]; dummy.looks['t] _ FALSE; dummy.endOfNode _ FALSE; dummy.looks['z] _ TRUE; PutRope ["----------", dummy]; document.Put [rule] END; TEditInputOps.CallWithLocks [Stuff] END; -- Paste Registations: PROC [] ~ BEGIN defaultCrops: LIST OF ROPE ~ LIST ["Design", "Selection", "Wysiwyg"]; defaultGoals: LIST OF ROPE ~ LIST ["Explain", "Tioga doc", "Raven300", "Raven384", "C2700", "Versatec", "ColorVersatec", "Erie", "IP only", "Hold"]; defaultCopies: ROPE ~ " 1"; defaultScale: ROPE ~ " 0.0"; bool: LIST OF ROPE ~ LIST ["No", "Yes"]; x: NAT _ 0; NewButton: PROC [name: ROPE, key: ATOM, val: REF _ NIL, trigger, newLine, editable: BOOL _ FALSE, x: NAT] RETURNS [xx: NAT _ 0] ~ BEGIN n: NAT ~ VFonts.StringWidth ["n"]; m: NAT ~ VFonts.StringWidth ["m"]; -- n & m space i, ii: CDPanel.Info; w, ww: NAT _ 0; ParWidth: PROC [par: REF] RETURNS [l: NAT] ~ BEGIN scrollBar: NAT ~ 13; -- may be it is only 12 pixels. l _ NAT.FIRST; WITH par SELECT FROM rope: ROPE => l _ VFonts.StringWidth [rope] + scrollBar; list: LIST OF ROPE => FOR r: LIST OF ROPE _ list, r.rest WHILE r # NIL DO l _ MAX [l, VFonts.StringWidth [r.first]] ENDLOOP; ENDCASE => ERROR END; -- ParWidth w _ VFonts.StringWidth [name] + n; xx _ x + w; i _ [text ~ name, border ~ trigger, width ~ w, space ~ 0, xpos ~ x]; x _ xx; IF trigger THEN CDPanel.Button [button: i, command: key] ELSE BEGIN CDValue.RegisterKey [key: key, registrationKey: masterKey]; CDValue.Store [key: key, value: val]; ww _ ParWidth [val] + n; xx _ x + ww; ii _ [cdValueKey ~ key, border ~ trigger, width ~ ww, space ~ 0, xpos ~ x]; CDPanel.Text [button: i, text: ii, editable: editable] END; IF newLine THEN {CDPanel.Line []; xx _ 0} END; -- NewButton [] _ CDProperties.RegisterProperty [masterKey, masterKey]; x _ NewButton [name ~ "Nectarine", trigger ~ TRUE, key ~ $NectarineCmd, x ~ x]; x _ NewButton [name ~ "What:", key ~ whatKey, val ~ defaultCrops, x ~ x]; x _ NewButton [name ~ "Where:", key ~ whereKey, val ~ defaultGoals, x ~ x]; x _ NewButton [name ~ "Copies:", key ~ copiesKey, val ~ defaultCopies, editable ~ TRUE, x ~ x, newLine ~ TRUE]; x _ NewButton [name ~ " in mm:", key ~ scaleKey, val ~ defaultScale, editable ~ TRUE, x ~ x]; x _ NewButton [name ~ "Current layer only:", key ~ monoLayerKey, val ~ bool, x ~ x, newLine ~ TRUE]; CDSequencer.ImplementCommand [key: $NectarineCmd, proc: NectarineCommand, queue: doQueue]; Commander.Register [key: "NCount", proc: Count, doc: "counts corner stitching tiles."]; Commander.Register [key: "NRedo", proc: Redo, doc: "Syntax: NRedo . Redoes the last Nectarine Print command on the same Interpress master but with the newly specified goal. The goal must be one of those specified in the field of the Nectarine line in the ChipNDale control panel. Default: the same as the last time around."]; Commander.Register [key: "PrintDesignOnVersatec", proc: PrintDesignOnVersatecCmd, doc: " []\nwill read fileName, convert it into an Interpress master, convert it into a PD file, and print it on the color Versatec. Default number of columns: 1."]; Commander.Register [key: "NSetMaxField", proc: SetMaxField, doc: " gets the status of the named XNS printer and sets Nectarine's field size to its medium size.\nHowever, IF printer.Equal [TimsToy, FALSE] THEN use dimensions specified in [Newton-XNS]C2700>C2700MarkerImpl.mesa at implementation time."] END; -- Registrations Count: Commander.CommandProc ~ BEGIN PerObject: SweepCollectableStorage.InfoProc ~ BEGIN IF type = CODE [CStitching.Tesselation] THEN tessCount _ tessCount + 1 ELSE IF type = CSTile THEN tileCount _ tileCount + 1; RETURN [TRUE] END; -- PerObject tessCount: INT _ 0; tileCount: INT _ 0; TRUSTED { SweepCollectableStorage.EnumerateCollectableStorage [PerObject] }; cmd.out.PutF ["tesselations = %g\n", IO.int [tessCount]]; cmd.out.PutF ["tiles = %g\n", IO.int [tileCount]] END; -- Count Redo: Commander.CommandProc ~ BEGIN where: ROPE ~ CommandTool.NextArgument [cmd]; savedKey: ATOM ~ lastPrint.key; IF lastPrint.ip.IsEmpty [] THEN BEGIN result _ $Failure; msg _ "No Interpress master cached !"; RETURN END; IF NOT where.IsEmpty [] THEN lastPrint.key _ SELECT TRUE FROM where.Equal ["ColorVersatec", FALSE] => $NColorVersatec, where.Equal ["Color400", FALSE] => $NColor400, where.Equal ["C2700", FALSE] => $C2700, where.Equal ["ThermalTransfer", FALSE] => $C2700, where.Equal ["Raven300", FALSE] => $NRaven300, where.Equal ["Raven384", FALSE] => $NRaven384, where.Equal ["Hornet", FALSE] => $NRaven384, where.Equal ["Bw400", FALSE] => $NBw400, where.Equal ["Versatec", FALSE] => $NVersatec, where.Equal ["Erie", FALSE] => $NPlateMaker, where.Equal ["PlateMaker", FALSE] => $NPlateMaker, where.Equal ["Tioga", FALSE] => $NPasteInTioga, where.Equal ["Tioga doc", FALSE] => $NPasteInTioga, where.Equal ["Paste", FALSE] => $NPasteInTioga, where.Equal ["Stuff", FALSE] => $NPasteInTioga, where.Equal ["IP only", FALSE] => $NmasterOnly, where.Equal ["IP", FALSE] => $NmasterOnly, where.Equal ["PeachExpand", FALSE] => $NPeachExpand, where.Equal ["hold", FALSE] => $Nhold, ENDCASE => $cacca; SELECT lastPrint.key FROM $NmasterOnly => msg _ lastPrint.ip; $NPasteInTioga => BEGIN Paste [lastPrint.ip, lastPrint.w, TRUE]; msg _ "Image deposed in temporary blinking iconic Tioga viewer." END; $cacca => BEGIN lastPrint.key _ savedKey; result _ $Failure; msg _ cmd.procData.doc END; ENDCASE => BEGIN rollPaperDeviceHint: REF Imager.Rectangle _ NEW [Imager.Rectangle _ lastPrint.w]; [] _ Nectarine.Print [lastPrint.ip, lastPrint.key, lastPrint.q, lastPrint.l, NOT lastPrint.r, rollPaperDeviceHint, NIL ! Nectarine.invalidPrinter => {result _ $Failure; msg _ cmd.procData.doc}] END END; -- Redo PrintDesignOnVersatec: PROC [name: ROPE, columns: INT] ~ BEGIN design: CD.Design _ CDIO.ReadDesign [name]; n: ROPE; rollPaperDeviceHint: REF Imager.Rectangle _ NEW [Imager.Rectangle]; IF (columns > 9) THEN ERROR; SELECT columns FROM 0 => RETURN; 1 => BEGIN [n, rollPaperDeviceHint^] _ Nectarine.DoInterpress [ design: design, chipNDaleWindow: CDOps.BoundingBox [design], clip: FALSE, onlySel: FALSE, abortFlag: NIL]; design _ NIL; -- Collect that garbage to make room in physical memory ! [] _ Nectarine.Print [masterName: n, printerKey: $NColorVersatec, mergeRegister: FALSE, sizeHint: rollPaperDeviceHint, abortFlag: NIL] END; ENDCASE => BEGIN bb: CD.Rect ~ CDOps.BoundingBox [design]; -- [x1, y1, x2, y2: INT] width: INT ~ (bb.x2 - bb.x1) / columns; window: CD.Rect _ bb; window.x2 _ window.x1 + width; FOR c: INT IN [1 .. columns] DO [n, rollPaperDeviceHint^] _ Nectarine.DoInterpress [ design: design, chipNDaleWindow: window, clip: TRUE, onlySel: FALSE, abortFlag: NIL]; IF (c = columns) THEN design _ NIL; [] _ Nectarine.Print [masterName: n, printerKey: $NColorVersatec, sizeHint: rollPaperDeviceHint, mergeRegister: FALSE, abortFlag: NIL]; window.x1 _ window.x2; window.x2 _ window.x2 + width ENDLOOP END END; -- PrintDesignOnVersatec PrintDesignOnVersatecCmd: Commander.CommandProc ~ BEGIN WDir: PROC RETURNS [wDir: ROPE] ~ BEGIN wDir _ FSExtras.GetWDir []; IF wDir.Equal ["[]<>"] THEN wDir _ cmd.command.Substr [0, FS.ExpandName[cmd.command].cp.base.start-1] END; -- WDir fileName: ROPE _ CommandTool.NextArgument [cmd]; columns: ROPE _ CommandTool.NextArgument [cmd]; cp: FS.ComponentPositions; [fileName, cp, ] _ FS.ExpandName [fileName, WDir []]; IF (cp.ext.length = 0) THEN fileName _ fileName.Concat [".Dale"]; fileName _ FS.FileInfo [name: fileName ! FS.Error => {result _ $Failure; msg _ error.explanation; CONTINUE}].fullFName; IF (result # $Failure) THEN TRUSTED BEGIN col: CARDINAL _ 1; IF NOT columns.IsEmpty THEN col _ Convert.IntFromRope [columns ! Convert.Error => {col _ 1; CONTINUE}]; msg _ IO.PutFR ["%g will be read, converted into an Interpress master, converted into a PD file, and printed in %g columns on %g.", IO.rope [fileName], IO.card [col], IO.rope [UserProfile.Token ["Nectarine.ColorVersatec", "Sleepy"]]]; Process.Detach [FORK PrintDesignOnVersatec [fileName, col]] END END; -- PrintDesignOnVersatecCmd SetMaxField: Commander.CommandProc ~ BEGIN printer: ROPE ~ CommandTool.NextArgument [cmd]; status: XNSPrint.PrinterStatus; service: ROPE; SpoolerStatusRope: PROC [spooler: XNSPrint.SpoolerStatus] RETURNS [ROPE] ~ {RETURN [SELECT spooler FROM available => "available", busy => "busy", disabled => "disabled", full => "full", ENDCASE => "unknown"]}; FormatterStatusRope: PROC [formatter: XNSPrint.FormatterStatus] RETURNS [ROPE] ~ {RETURN [SELECT formatter FROM available => "available", busy => "busy", disabled => "disabled", ENDCASE => "unknown"]}; PrinterStatusRope: PROC [printer: XNSPrint.MarkingEngineStatus] RETURNS [ROPE] ~ {RETURN [SELECT printer FROM available => "available", busy => "busy", disabled => "disabled", needsAttention => "needs attention", needsKeyOperator => "needs key operator", ENDCASE => "unknown"]}; IF printer.IsEmpty THEN {result _ $Failure; msg _ "Specify a XNS printer name"; RETURN}; [service, status] _ XNSPrint.GetPrinterStatus [printer ! XNSPrint.Error => {result _ $Failure; msg _ explanation; CONTINUE}]; IF (result # $Failure) THEN BEGIN msg _ service.Cat ["\n\tspooler: ", SpoolerStatusRope [status.spooler], "\n\tformatter: ", FormatterStatusRope [status.formatter]]; msg _ msg.Cat ["\n\tprinter: ", PrinterStatusRope [status.printer], "\n\tfirst medium: ", status.media.first]; IF (printer.Equal ["TimsToy", FALSE] OR printer.Equal ["TimsToy:PARC:xerox", FALSE]) THEN BEGIN dpi: REAL ~ 300.0; sSize: NAT ~ 2672; fSize: NAT ~ 304*8; -- bits fSizeInMM: REAL ~ fSize/dpi -- in inches -- * 25.4; sSizeInMM: REAL ~ sSize/dpi -- in inches -- * 25.4; bottomOffsetInMM: REAL ~ 0.036 * 1000.0; fudge: REAL ~ 6.5; NectarinePd.field _ [x: fudge, y: bottomOffsetInMM, w: fSizeInMM, h: sSizeInMM-4.0]; IF NOT status.media.first.Equal ["usLetter"] THEN msg _ msg.Cat [", but Nectarine only knows about usLetter"] END ELSE BEGIN size: XNSPrint.PaperDimensions _ XNSPrint.GetPaperDimensions [status.media.first]; NectarinePd.field _ [x: 0.0, y: 0.0, w: Float [size.width], h: Float [size.length]] END; msg _ IO.PutFR ["%g\n\tfield size in mm: [x, y, w, h] = [%g, %g, %g, %g]", IO.rope [msg], IO.real [NectarinePd.field.x], IO.real [NectarinePd.field.y], IO.real [NectarinePd.field.w], IO.real [NectarinePd.field.h]] END END; -- SetMaxField ExplainGoals: PROC [] ~ BEGIN Plop: PROC [plup, plip, plap: ROPE] ~ BEGIN TerminalIO.PutRope [plup.Cat [": print on ", UserProfile.Token [Rope.Cat ["Nectarine.", plup], plip]]]; TerminalIO.PutRope [Rope.Cat [", a ", plap, " printer.\n"]] END; -- Plop TerminalIO.PutRope ["Tioga doc: copy in the Tioga document at the caret.\n"]; Plop ["Raven300", "Quoth", "black & white XNS Interpress"]; Plop ["Raven384", "your disk", "black & white Press"]; Plop ["Versatec", "Sleepy", "black & white Versatec"]; Plop ["ColorVersatec", "Sleepy", "colour Versatec"]; Plop ["C2700", "MtFuji", "thermal colour XNS Interpress"]; Plop ["Erie", UserProfile.Token ["Nectarine.PlatemakerSeparations"], "Platemaker"]; TerminalIO.PutRope ["Explain: jot down this explanation.\n"]; TerminalIO.PutRope ["hold: hold the result in form of a page. The next time the 'where' parameter is different from 'hold', prepend to it the previous pages and create a multi-page Interpress master.\n\n"] END; -- ExplainGoals MichaelsMessage: PROC ~ BEGIN IF NOT UserProfile.Boolean [key: "Nectarine.SubstituteColors", default: TRUE] THEN BEGIN TerminalIO.PutRope ["Warning, you are using your personal named ChipNDale colors. Nobody else will be able to see your document unless you provide them with your colors. Refer to the documentation for an option to automatically substitute your personal colors by univerally known colors (User profile entry Nectarine.SubstituteColors). Named colors are explained in ColorRegistryDoc.tioga.\n"]; ViewerOps.BlinkDisplay END END; -- MichaelsMessage ImportantMessage: PROC [msg: ROPE] ~ BEGIN TerminalIO.PutRope [msg]; TerminalIO.PutRope ["\n"]; MessageWindow.Clear []; MessageWindow.Append [msg]; MessageWindow.Blink [] END; -- ImportantMessage CSTile _ SafeStorage.GetCanonicalReferentType [CStitching.NewTesselation[].FindTile[[0,0]]]; Registations []; TerminalIO.PutRope ["Nectarine package loaded.\n"]; END. * NectarineCommand.mesa Copyright Σ 1986, 1987, 1988 by Xerox Corporation. All rights reserved. Giordano Bruno Beretta, December 21, 1988 5:59:12 pm PST gbb October 25, 1988 10:50:00 am PDT Louis Monier November 2, 1988 11:56:11 am PST Implements the Nectarine commands for interactive use in ChipNDale. Fuzzless and sweeter than peaches. This global variable is used to implement the Redo command. Called by ChipNDale upon activation of the command. Protected procedure. The exception: the user does not know what he is doing (may be he is just nervous). MichaelsMessage []; Interpret what. Interpret where. ImportantMessage ["Are you sure you did not want to use the printer server 'PeachExpand' (see doc)?"]; Interpret how many. This is a hack to work around a bug in CDPanel: the initialization of the defaults is spurious. Interpret scale (lambda in millimetres). This is a hack to work around a problem in CDPanel: the initialization of the defaults is spurious. Interpretate necessity to print only one layer. This is a hack to work around a problem in CDPanel: the initialization of the defaults is spurious. Create an Interpress master if necessary. The following is not a hack. In schematics the cells may have a border. On the screen this border is one pixel wide, but with Interpress we have to specify a concrete width in millimetres. We choose to make it { l wide. If the border has a width, it takes some finite amount of space on the paper. It would be natural to use this space inside the cell. However, the designers exploit the fact that on the screen the border has no width and put text flush to the border. In order to preserve such text, Nectarine is forced to print the border outside the cell. This means, that the border can now be outside the field on the medium. This is why here we cheat and increase the window by l on each side. IF ((cropKey = $NectarineAll) AND (scale # 0.0) AND ((printKey = $NmasterOnly) OR (printKey = $NRaven300) OR (printKey = $C2700) OR (printKey = $NRaven384) OR (printKey = $NPlateMaker))) THEN BEGIN I know, I could write this more succinctly, but this is more readable and speed is not an issue here. Print if asked to do so. You would probably expect here a direct call of Nectarine, since the implementation is reentrant. However, I wanted to avoid two print commands on the same design, because this would force me to implement a file name manager and to place on the user the burden of descrying it. What I really wanted to do was to prevent multiple calls on the same design, but to allow parallel calls on different designs. Unfortunately, currently there are no provisions for this in ChipNDale: resources are global to ChipNDale and there are none local to designs (at least as long as you imperatively need a lightweight abort capability). Surely I could implement a hack, but there are no hacks in Nectarine. Pastes the Interpress master in file name and with bounding box bb at the current Tioga selection. The appropriate scaling is being implemented in Tioga and in TiogaToInterpress. I misteri della vita e della morte. Writes into document the characters in r using the attributes of the sample character attr. Safely attaches a property with key prop and value val to the character char. Takes the working area Tioga document document and stuffs it into the current selection. Insert block node containing a CR. Why??? Insert a rule node as required by the CSL & EDL publication style. Insert an artworkFigure node, with a postfix prop for lead and ident, bounds and with Artwork containing the IP master. The node contains a rope which becomes visible when ArtworkInterpress is off. ip _ PutProp [ip, $Postfix, IO.PutFR ["%g mm topLeading %g mm topIndent %g mm bottomLeading", IO.real [bb.y+bb.h+space], IO.real [bb.y+bb.h+space], IO.real [-bb.y+space/2.0]]]; -- margin in the document Insert a nested artworkCaption node with a hint rope. Insert a rule node as required by the CSL & EDL publication style. Take the contents of document and stuff it into the current Tioga selection. If there is no selection, nothing happens. defaultGoals: LIST OF ROPE ~ LIST ["Explain", "Tioga doc", "Raven300", "Raven384", "Bw400", "Versatec", "PeachExpand", "ColorVersatec", "Color400", "PlateMaker", "IP only", "hold"]; defaultGoals: LIST OF ROPE ~ LIST ["Explain", "Tioga doc", "Raven300", "Raven384", "Bw400", "Color400", "Versatec", "ColorVersatec", "Erie", "IP only", "Hold"]; This is a hack because there is a bug in the current version of CDPanel that causes all buttens but the first on the line to be displayed outside the screen (x = 2000). Returns the longest rope in a list. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] [type: SafeStorage.Type, size: INT, object: LONG CARDINAL] RETURNS [continue: BOOLEAN] [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Syntax: NRedo . Redoes the last Print command on the same Interpress master but on the newly specified goal. The goal must be one of those specified in the field of the Nectarine line in the ChipNDale control panel. Default: the same as the last time around. The problem here is that now the input focus is in the Command Tool viewer, which surely is not the one into which the poor user wanted to paste his image. Therefore, a new Tioga viewer is created and used as a temporary repository for the image. To allow forking off the printing command. NOTE: It is not possible to produce a multi-page Interpress master as for XNS printers, because Peach printers loose the communication in the time between starting and finishing printing, so that they cannot fetch page 2. Do not overlap columns, because it would make it hard to cut the margin. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Guarantees that the working directory is not the root. [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL] Open [Newton-XNS]C2700>C2700MarkerImpl.MakePrinterSampleMap Upon popular demand, we explain the entries in the Where menu. Plaps plop for plop at plip. Plop ["Bw400", "MtFuji", "black & white thermal"]; Plop ["Color400", "MtFuji", "colour thermal"]; For 7.0. Writes a message in the ChipNDale terminal viewer and in the Message Window at the top of the LF screen and makes it blink. TerminalIO.PutF ["%l%g%lThe handling of the colors specified in the Interpress masters has been implemented with utmost diligence and care. The implementor of Nectarine declines any responsability for the rendition of the colors, which is outside his sphere of influence. To discover which and why a certain colour is used for a ChipNDale layer use the command Nquery. For the same information on all layers use the command Nectarine with switch e.%l\n\n", IO.rope ["b"], IO.rope ["Disclaimer. "], IO.rope ["Bi"], IO.rope [" "]]; ExplainGoals [] gbb September 5, 1986 11:25:18 am PDT Uses the new parameter sizeHint of the Nectarine print procedure. changes to: DoIt (local of NectarineCommand) gbb September 18, 1986 8:03:57 pm PDT Eliminated the call back stuff for the Nectarine property on the design (a former optimization). changes to: DoIt (local of NectarineCommand), Registations gbb September 22, 1986 1:59:48 pm PDT Added PlateMaker. changes to: DoIt (local of NectarineCommand), Registations gbb September 26, 1986 4:01:22 pm PDT Added an explaination goal for confused users. changes to: DIRECTORY, IMPORTS, DoIt (local of NectarineCommand), Registations, ExplainGoals, Plop (local of ExplainGoals) gbb October 14, 1986 3:53:59 pm PDT Added the Redo command. changes to: ~, DoIt (local of NectarineCommand), Registations, Count, Redo, ExplainGoals, DIRECTORY gbb December 5, 1986 1:08:16 pm PST Added Raven384. changes to: DoIt (local of NectarineCommand), Registations, Redo, ExplainGoals gbb December 18, 1986 4:49:05 pm PST Introduced a check for empty selections. changes to: DoIt (local of NectarineCommand) gbb February 3, 1987 10:15:03 am PST Added the ability to use a fixed value for  specified in mm. changes to: DoIt (local of NectarineCommand), Registations. gbb February 10, 1987 3:20:10 pm PST Added the ability to print only a single layer. changes to: DIRECTORY, IMPORTS, ~, DoIt (local of NectarineCommand), Registations gbb February 20, 1987 4:44:26 pm PST Added hacks to circumvent a spurius problem in CDPanel, which all the sudden since a couple of days does not always initialize the defaults. changes to: DoIt (local of NectarineCommand) gbb March 16, 1987 3:08:29 pm PST Added break-up of document in a sequence of A4 pages for page printers. changes to: DIRECTORY, IMPORTS, ~, DoIt (local of NectarineCommand) gbb April 1, 1987 5:57:32 pm PST Added the hold buffer. changes to: ~, NectarineCommand, DoIt (local of NectarineCommand), Registations, Redo, ExplainGoals gbb April 10, 1987 12:06:21 pm PDT Put in a patch to circumvent a problem in CDPanel. changes to: NewButton (local of Registations) gbb June 16, 1987 3:13:14 pm PDT Less insistence regarding the use of named colours. changes to: DoIt (local of NectarineCommand), ExplainGoals, MichaelsMessage gbb December 3, 1987 11:03:12 am PST Made printing abortable from the ChipNDale viewer. changes to: DoIt (local of NectarineCommand) gbb December 3, 1987 5:44:22 pm PST Add a command tool command to print designs on the color Versatec (to be included in comman files. changes to: DIRECTORY, IMPORTS, PrintDesignOnVersatec, PrintDesignOnVersatecCmd, WDir (local of PrintDesignOnVersatecCmd), ExplainGoals gbb December 14, 1987 3:38:59 pm PST Multi-column printing. changes to: DIRECTORY, IMPORTS, Redo, PrintDesignOnVersatec: can do it on multiple columns, PrintDesignOnVersatecCmd: looks for a number after the design name. gbb June 3, 1988 10:42:14 am PDT Adjurned to current style for Blue and White. changes to: Paste gbb July 25, 1988 3:26:23 pm PDT Introduced a user profile option to follow the Bland style instead of the CSL publication style. changes to: ~, Paste gbb September 19, 1988 10:14:12 am PDT Added C2700 XNS service changes to: DoIt (local of NectarineCommand), Registations, Redo, ExplainGoals gbb September 21, 1988 4:18:08 pm PDT Added new command to set the field size to the medium size for XNS printers, except for Tim's Toy, for which the constants in the server code as of September 21, 1988 4:13:37 pm PDT are set. Command syntax: NSetMaxField changes to: Registations, SetMaxField, DIRECTORY, IMPORTS gbb September 22, 1988 10:30:49 am PDT Added fudge for portion of bitmap not printed changes to: SetMaxField gbb October 7, 1988 4:43:41 pm PDT Tuning of fudge. Seems to depend on how well paper cassette in inserted in printer. changes to: SetMaxField Κ˜codešœ™KšœH™HKšœ8™8K™$K™-—K™K™gcode2šΟk ˜ Kšœœ˜Kšœœ?˜GKšœ œ˜Kšœ œ˜$Kšœœ˜Kšœ œ˜Kšœœ˜Kšœœ*˜7Kšœ œ#˜5Kšœ œ+˜Kšœœ˜:Kšœœ˜1šœœ˜+Kšœ‘˜‘Kšœ˜Kšœ˜—Kšœ0‘’‘œ˜F—Kš œ(œœœœœœ˜ΘM™š˜Kšœœ1˜8Kšœ_™_Kšœ œ ˜Kš œ œ œœœœ˜XKšœ˜—Mšœ(™(š˜Kšœœ0˜7Kšœc™cKšœ œ ˜Kš œ œ œœœœ˜XKšœœ.œ˜SKšœ1˜5Kšœ˜—M™/š˜Kšœœ4˜;Kšœc™cKšœ œ ˜#Kšœ œ œœœœœ˜bšœ œ˜Kšœ6˜6Kšœ>œœ˜fKš˜—Kšœ˜—Mšœ)™)šœœ˜%Kšœœ ˜ KšΟgœœ(˜-šœ ˜Kšœ6˜6šœ˜Kšœœ ˜Kšœ%œ˜+Kšœ ˜ šœœœ˜-KšœF˜FKš‘’‘˜ Kš˜—Kšœ˜—šœ˜Kšœ@˜@Kšœ!˜!Kšœœ˜šœ œœ˜KšœB˜BKš‘’‘˜ Kšœ˜—šœ*œœ˜=Kšœœœ$œ˜CJšœ˜—šœ˜Kšœ:‘’‘œ˜IKšœ]˜]Kšœœ˜—Kšœ&˜&Kšœ˜—Kšœœ˜—Kš œ’œΑΟmœ£œή£œ™ΕKš œ£œ£œ£œ£œ˜Bšœœœ˜-Kšœœœœœœœœ™ΕKšœœ˜KšœA ˜IKšœ- ˜5Kšœ œ$£œ ˜@Kšœ œ$£œ ˜@Kšœ œ£œ  ˜?Kšœ œ£œ  ˜@Kšœ œ ˜?Kšœœ  ˜=Mšœ%œœ˜CKšœ"œ œ˜:KšœEœ˜\KšœU˜Ušœœœ ˜ šœœœ˜#Kšœ`œžœ œœœœœ4˜ͺKšœ$˜$Kšœ-˜-Kšœ˜—Kšœ=˜=Kšœ$˜$Kšœ-˜-Kšœ˜—Kšœ& ˜.Kš˜—Kšœœ›œY˜ώšœœ˜!Kšœœœœ˜Pšœ˜ K™eKšœœœ@˜NKšœœœ@˜NKšœœ ˜5Kšœœ ˜5Kšœ'˜'Kšœ&˜&Kš˜—Kš˜—šœ˜ Kšœœœ.œ˜OKšœ˜—Kšœ?˜?Kšœ ˜ —M™Kšœw  ˜‚šœ ˜Kšœœ˜Kšœ0˜0Kšœr˜ršœ˜Kšœœ ˜9KšœœP‘œ˜ΪKšœ˜——Kšœ6˜6Kšœ ˜ —Mšœ.˜.šœ9˜9KšœΈ™Έ—Kšœ ˜—š Ÿœœœ#œœ˜Ošœ%Οeœ₯œs™΅KšΟo#™#—Kšœœ ,˜TKšœ7 ˜RKš œ-œœœœœœ˜TKšœ>˜>Kšœœ) ˜Kšœί˜ίKšœH˜HKšœ'œ˜,Kšœ*˜0—šœB™BKšœœœ˜0Kšœ˜Kšœ˜—Kšœ˜—šœ₯œZ™wKšœ#˜#—Kšœ ˜ —šŸ œœ˜K•StartOfExpansion`[tech: CD.Technology _ NIL, name: ROPE, border: BOOL _ FALSE, cdValueKey: REF ANY _ NIL]š œœœœœ$˜EKš œœœœœ”™΅Kš œœœœœ™ Kš œœœœœs˜”Kšœœ ˜Kšœœ ˜K–`[tech: CD.Technology _ NIL, name: ROPE, border: BOOL _ FALSE, cdValueKey: REF ANY _ NIL]š œœœœœ˜(Kšœœ˜ šŸ œœœœœœœœœœœ˜‡Kšœ¨™¨Kšœœ œ ˜TKšœœ˜$š Ÿœœœœœ˜2K™#Kšœ œ ˜4Kšœœœ˜šœœ˜Kšœœ.˜8šœœœœœœœœœœ˜IKšœœ"˜)Jšœ˜—Kšœ˜—Kšœ  ˜—Mšœ"˜"Kšœ ˜ KšœD˜DK˜Kšœ œ)˜8šœ˜ Kšœ;˜;Kšœ%˜%Kšœ%˜%KšœK˜KKšœ6˜6Kšœ˜—Kšœœ˜)Kšœ  ˜—Mšœ:˜:Kšœ-œ˜OKšœI˜IKšœK˜KKšœRœœ˜oKšœQœ ˜^Kšœ^œ˜dKšœZ˜ZKšœW˜WKšœΣ˜ΣKšœ‰˜‰KšœΞ˜ΞKšœ  ˜—šŸœ˜$JšΠck=§™HšŸ œ%˜3Kš§W™WJšœœœ˜FJšœœœ˜5Jšœœ˜ Kšœ  ˜—Mšœ œ˜Kšœ œ˜KšœE˜LKšœ%œ˜9Kšœœ˜1Kšœ ˜ —šŸœ˜#Jš§=§™HJšœ™Jšœœ"˜-Kšœ œ˜šœœ˜%Kšœ:˜:Kš‘˜Kšœ˜—š œœœ œœ˜=Kšœœ˜8Kšœœ˜.Kšœœ ˜'Kšœ œ ˜1Kšœœ˜.Kšœœ˜.Kšœœ˜,Kšœœ ˜(Kšœœ˜.Kšœœ˜,Kšœœ˜2Kšœœ˜/Kšœœ˜3Kšœœ˜/Kšœœ˜/Kšœœ˜/Kšœœ˜*Kšœœ˜4Kšœœ ˜&Kšœ ˜—šœ˜Kšœ#˜#šœ˜K™φKšœ"œ˜(Kšœ@˜@Kšœ˜—šœ ˜KšœE˜EKšœ˜—šœ˜Kšœœœ"˜QKšœMœ#œK˜ΑKš˜——Kšœ ˜ —š Ÿœœœ œ˜>K™*K™έKšœœ œœ˜4Kšœœœ˜CKšœœœ˜šœ ˜Kšœ‘œ˜ šœ˜ Kšœxœ œ œ˜ŸKšœ œ 9˜GKšœQœ,œ˜†Kšœ˜—šœ˜Kšœœ$ ˜BKšœœœ ˜'Kšœœ ˜Kšœ˜šœœœ˜Kšœdœ œ œ˜ŠKšœœ œ˜#Kšœpœ œ˜‡K™HKšœ4˜4Kš˜—Kš˜——Kšœ ˜—šŸœ˜7Jš œœ œœœœœ™Hš Ÿœœœœ˜'K™6Kšœ˜Kšœœœ)˜eKšœ ˜ —Kšœ œ"˜0Kšœ œ"˜/Kšœœ˜Mšœœ ˜5Kšœœ&˜AKšœ œœ7œ ˜wšœœœ˜)Kšœœ˜šœœ˜Kšœ@œ˜K—Kš œœ|œœ œA˜κKšœœ'˜;Kš˜—Kšœ ˜ —šŸ œ˜*Jš§=§™HKšœ œ"˜/Kšœ)œ˜.šŸœœ#œœ˜JKš œœœ œSœ˜†—šŸœœ'œœ˜PKš œœœ œCœ˜x—šŸœœ)œœ˜PKš œœœ œ’œ˜Ε—Mšœœ9‘œ˜XKšœrœ˜}šœœ˜!Kšœƒ˜ƒKšœn˜nš œœœ&œœ˜_KšœJ™JKšœœœœ  ˜AKšœ œ  œ˜3Kšœ œ  œ˜3Kšœœ˜(Kšœœ˜KšœT˜TKšœœ'œ<˜mKš˜—šœ˜ KšœR˜RKšœS˜SKšœ˜—Kš œœCœ œœœœ˜ΥKš˜—Kšœ ˜—šŸ œœ˜Kšœ3₯œ™>šŸœœœ˜+K™Kšœg˜gKšœ;˜;Kšœ ˜ —MšœM˜MMšœ;˜;Kšœ6˜6Kšœ2™2Kšœ6˜6Kšœ4˜4Kšœ.™.Kšœ:˜:KšœS˜SMšœ=˜=KšœΝ˜ΝKšœ ˜—šŸœœ˜K™š œœBœœ˜XKšœŠ˜ŠKšœ˜Kš˜—Kšœ ˜—šŸœœœ˜*Kšœ^œ™{Kšœ4˜4KšœJ˜JKšœ ˜—Lšœ\˜\Lšœ˜Lšœ3˜3Kš œΙœ œœœ ™‘L™—Lšœ˜™%Kšœ₯œ"™AKšœ Οrœ™,—™%K™`Kšœ ¨œ¨™:—™%Kšœ™Kšœ ¨œ¨™:—™%K™.Kšœ ¨œ¨"œ™z—™#K™Kšœ ¨œ¨4™c—™#K™Kšœ ¨œ¨"™N—™$K™(Kšœ ¨œ™,—™$K™=Kšœ ¨œ¨œ™;—™$K™/Kšœ ¨œ¨™Q—™$KšœŒ™ŒKšœ ¨œ™,—™!K™GKšœ ¨œ™C—™ K™Kšœ ¨œ¨"™c—™"K™2Kšœ ¨ œ™-—™ K™3Kšœ ¨œ¨™K—™$K™2Kšœ ¨œ™,—™#K™bKšœ ¨Iœ$¨™‡—™$K™Kšœ ¨/œ¨œ+™Ÿ—™ K™-Kšœ ¨™—™ K™`Kšœ ¨™—™&K™Kšœ ¨œ¨"™N—™%Kšœκ™κKšœ ¨-™9—™&K™-Kšœ ¨ ™—™"K™SKšœ ¨ ™—K™—…—gd­€