gWidgets/0000755000176000001440000000000013652210053012054 5ustar ripleyusersgWidgets/NAMESPACE0000644000176000001440000001532713423300546013306 0ustar ripleyusersimportFrom("stats","update") importFrom("methods","show") importFrom("utils", "installed.packages") ## functions to export export("guiToolkit","gwCat", "gtoolkit") ## constructors export("glabel", "gbutton", "gcheckbox", "gradio", "gdroplist","gcombobox", "gcheckboxgroup", "gspinbutton", "gslider", "gedit", "gtext", "gaction", "gmenu", "gtoolbar", "gtable", "gdf", "gdfnotebook", "gtree", "gfile", "gfilebrowse", "gcalendar", "ggraphics", "ggraphicsnotebook", "ghtml","gimage", "gsvg", "gstatusbar", "gseparator", "gcommandline", "ghelp", "ghelpbrowser", "ggenericwidget", "gformlayout","gvarbrowser", # "gdynamicselect", "gwindow", "ggroup", "gframe", "gexpandgroup", "gnotebook", "glayout", "gpanedgroup", "galert", "gmessage", "ginput", "gconfirm", "gbasicdialog", "galert", "addStockIcons","getStockIcons", "stockIconFromClass","stockIconFromObject", "toolkitProvidesWidget" ) ## export toolkits and the basic gui-classes exportClasses("guiWidgetsToolkit", "guiWidgetsToolkitRGtk2", "guiWidgetsToolkitrJava", "guiWidgetsToolkitSJava", "guiWidgetsToolkittcltk", "guiWidgetsToolkitRwxWidgets", "guiWidget","guiComponent","guiContainer","guiDialog", "gWidgetANY","gComponentANY","gContainerANY","guiDialog", "guiWidgetOrNULL", "guiDialog", "gAction", "gButton", "gCalendar", "gCheckbox","gCheckboxGroup", "gCombobox","gCommandline", "gCommandlineANY", "gDfNotebook", "gEdit", "gExpandGroup", "gFilebrowse", "gFormLayout","gFormLayoutANY", "gFrame", "gGenericWidget", "gGenericWidgetANY", "gGraphics", "gGraphicsNotebook", "gGridComponent", "gDf", "gTable", "gGroup", "gHelp", "gHelpBrowser", "gHelpANY", "gHelpbrowserANY", "gHtml", "gImage", "gLabel", "gLayout", "gMenu", "gNotebook", "gPanedGroup", "gRadio", "gSeparator", "gSlider", "guiComponentRangeSelector", "gSpinbutton", "gStatusbar", "gSvg", "gText", "gToolbar", "gTree", "guiComponentWithItems", "gVarBrowser", "gWindow" ) ## these are used by others but defined here. export("editSubsetDialog","editSelectDialog", "editFormulaDialog",".fixFontMessUp", "str2") exportMethods( "show", "[", "svalue", "svalue<-", "add", "addSpace", "addSpring", "insert", "delete", "dispose", "visible", "visible<-", "enabled", "enabled<-", "editable", "editable<-", "size", "size<-", "focus", "focus<-", "tooltip<-", "defaultWidget","defaultWidget<-", "font", "font<-", "undo", "redo", "tag", "tag<-", "id", "id<-", "isExtant", "addhandler", "addHandler", "addhandlerchanged", "addHandlerChanged", "addhandlerkeystroke","addHandlerKeystroke", "addhandlerclicked", "addHandlerClicked", "addhandlerdoubleclick","addHandlerDoubleclick", "addhandlerrightclick","addHandlerRightclick", "addhandlercolumnclicked", "addHandlerColumnClicked", "addhandlercolumndoubleclick","addHandlerColumnDoubleclick", "addhandlercolumnrightclick","addHandlerColumnRightclick", "addhandlerfocus","addHandlerFocus", "addhandlerblur","addHandlerBlur", "addhandlerdestroy", "addHandlerDestroy", "addhandlerexpose", "addHandlerExpose", "addhandlerunrealize", "addHandlerUnrealize", "addhandlermousemotion","addHandlerMouseMotion", "addhandleridle", "addHandlerIdle", "addpopupmenu", "addPopupmenu", "add3rdmousepopupmenu","add3rdMousePopupmenu", "adddropsource", "addDropSource", "adddropmotion", "addDropMotion", "adddroptarget", "addDropTarget", "removehandler", "removeHandler", "blockhandler", "blockHandler", "unblockhandler", "unblockHandler", ".glabel", ".gbutton", ".gcheckbox", ".gradio", ".gdroplist", ".gcheckboxgroup", ".gspinbutton", ".gslider", ".gedit", ".gtext", ".gaction", ".gmenu", ".gtoolbar", ".gtable", ".gdf", ".gdfnotebook", ".gtree", ".gfile", ".gfilebrowse", ".gcalendar", ".ggraphics", ".ggraphicsnotebook", ".ghtml",".gimage", ".gsvg", ".gstatusbar", ".gseparator", ".gcommandline", ".ghelp", ".ghelpbrowser", ".ggenericwidget", ".gformlayout", ".gvarbrowser", ## ".gdynamicselect", ".gwindow", ".ggroup", ".gframe", ".gexpandgroup", ".gnotebook", ".glayout", ".gpanedgroup", ".svalue", ".svalue<-", ".leftBracket", ".leftBracket<-", ".add", ".addSpace", ".addSpring", ".insert", ".delete", ".dispose", ".visible", ".visible<-", ".enabled", ".enabled<-", ".editable", ".editable<-", ".size", ".size<-", ".focus", ".focus<-", ".tooltip<-", ".defaultWidget",".defaultWidget<-", ".font", ".font<-", ".undo", ".redo", ".tag", ".tag<-", ".id", ".id<-", ".isExtant",".toolkitProvidesWidget", ".removehandler", ".blockhandler", ".unblockhandler", ".addhandler", ".addhandlerchanged", ".addhandlerkeystroke", ".addhandlerclicked", ".addhandlerdoubleclick", ".addhandlerrightclick", ".addhandlercolumnclicked", ".addhandlercolumndoubleclick", ".addhandlercolumnrightclick", ".addhandlerfocus", ".addhandlerblur", ".addhandlerdestroy", ".addhandlerexpose", ".addhandlerunrealize", ".addhandlermousemotion", ".addhandleridle", ".addpopupmenu", ".add3rdmousepopupmenu", ".adddropsource", ".adddropmotion", ".adddroptarget", ".galert",".gmessage", ".ginput", ".gconfirm", ".gbasicdialog", ".gbasicdialognoparent",".galert", ".addStockIcons",".getStockIcons", ".stockIconFromClass",".stockIconFromObject", "update",".update", "length",".length", "dim",".dim", "dimnames",".dimnames", "dimnames<-",".dimnames<-", "names",".names", "names<-",".names<-", "getToolkitWidget",".getToolkitWidget", ".callToolkitMethod", ".getToolkitProperty", ".setToolkitProperty" ) export("$.guiWidget") export("[[.guiWidget") export("[[<-.guiWidget") ## put into toolkit only (RGtk2) ##export("as.gWidget") ##S3method("as.gWidget","default") S3method("$", guiWidget) S3method("[[", guiWidget) S3method("[[<-", guiWidget) importFrom("methods", "callNextMethod", "is", "new") importFrom("utils", "RweaveEvalWithOpt", "assignInNamespace", "getFromNamespace", "head", "help", "help.search", "menu") gWidgets/ChangeLog0000644000176000001440000001764411703141567013652 0ustar ripleyusers2012-01-10 john verzani * DESCRIPTION (Suggests): put in cairoDevice into Suggests to keep out a warning in R CMD check. 2011-08-07 john verzani * R/toolkitClasses.R (guiToolkit): new function toolkit to return string naming toolkit (for comparison) 2011-07-27 john verzani * R/dialogs.R: forgot to pass parent along in galert 2011-07-26 john verzani * R/gslider.R (gslider): added length.out, along.with arguments * R/gspinbutton.R: added length.out, along.with arguments 2011-07-22 john verzani * man/gWidgets-dialogs.Rd (icon): doc changes to gbasicdialog * R/glayout.R (glayout): worked on [ method to return subset of one row or one column. (Before just an item) 2011-07-13 john verzani * DESCRIPTION (Version): version bump 2011-04-07 john verzani * man/gWidgets-methods.Rd: put in new methods editable[<-]. Can be used to query or set whether a widget is editable. E.g, gedit text may be locked. 2011-01-05 john verzani * R/gedit.R (gedit): added new argument initial.msg to display a grayed out message when no intial value is specified 2010-12-30 john verzani * R/gaction.R (gaction): added parent argument (like gWidgetsWWW), allows one to insert key accelerator into toplevel window of parent 2010-10-17 john verzani * R/gcheckbox.R: added use.togglebutton argument to use toggle button in place of checkbox 2010-10-15 john verzani * R/gcommandline.R: updated this widget, works better with Qt, tcltk 2010-10-10 john verzani * R/gcheckbox.R: added ... to gcheckbox! 2010-10-05 john verzani * R/ghelp.R (.findHelpPage): cleaned up code thanks to Josef L. and his textConnection snippet 2010-09-19 john verzani * R/ghelp.R: reworked this, made work for all three toolkits 2010-08-22 john verzani * R/aaaGenerics.R (gwindow): added check to options for whether visible=TRUE should be default. 2010-07-06 john verzani * man/ggraphics.Rd: new example 2010-05-19 john verzani * man/gimage.Rd: new help page example contributed by Richie Cotton. 2010-04-29 verzani * R/aaaGenerics.R (toolkitProvidesWidget): new method to see if widget is provided by toolkit. E.g. is gsvg defined, or ggraphics? 2010-04-18 verzani * R/gvariables.R: fix fonts -- use c, not list 2010-04-06 john verzani * R/aaaGenerics.R: removed gWIdgetsWWW from possible choices. 2010-04-02 john verzani * R/aaaGenerics.R: added guiToolkitQt, added generics undo/redo 2009-11-15 john verzani * R/aaaGenerics.R: add column clicked, doubleclick and rightclick to API for use with gdf gtable. 2009-09-09 john verzani * inst/tests/ex-gdialogs.R: added interactive() check to this one. Hanging in tcltk? 2009-03-07 john verzani * R/gcommandline.R: fixed little bug with history, redid layout. Still not great 2009-03-05 john verzani * R/zzz.R (popup): removed popup when no toolkits are installed so that automatic builds go through. 2009-02-13 john verzani * R/ggenericwidget.R: Fixes to handling of functino 2009-02-12 john verzani * R/ggenericwidget.R: fix to cli call (thanks to Diego Zardetto) 2008-12-15 john verzani * R/aaaGenerics.R: put in code for gbasicdialog to be able to use arbitrary modal dialogs with tcltk and others. 2008-12-09 john verzani * R/ghelp.R: fixes to ghelp for gWidgetstcltk 2008-12-04 john verzani * R/aaaGenerics.R (ladd): fixed "add" to weed out extra arguments based on being container component. 2008-10-21 john verzani * man/gtable.Rd: fix to man page for svalue with sorted data frames 2008-10-01 john verzani * R/gformlayout.R: New constructor for laying out forms (dialogs) using a list to specify widgets. 2008-07-20 john verzani * inst/doc/gWidgets.Rnw (section*{Abstract:}): updated vignette: Scode -> <<>>=; = -> <-, minor fixes 2008-05-27 jverzani * R/ghelp.R: try to fix ghelp to work under windows by putting in chmhelp=FALSE, htmlhelp=FALSE ala Rpad. 2008-05-19 jverzani * R/aaaGenerics.R: changed .svalue generic 2008-04-25 jverzani * inst/tests/test-window.R (f): Added tests to tests director 2008-04-23 jverzani * R/aaaGenerics.R: changed location argument to parent in gwindow. Added parent argument to gdialogs. * R/common.R (gwCat): added function to quiet messages. Set option gWidgetsDebug to non null to hear warning messages 2008-04-12 jverzani * R/aaaGenerics.R: added blockHandler, unblockHandler 2008-04-04 jverzani * man/ggroup.Rd: names should refer to label for gframe, gexpandgroup 2008-04-02 jverzani * R/aaaGenerics.R (as.gWidget): added new S3 generic for coercion, mostly with RGtk2 implementation. 2008-03-31 jverzani * NAMESPACE: added addHandlerMouseMotion 2008-02-14 jverzani * R/aaaGenerics.R: Added defaultWidget method. Implemented in RGtk2. 2008-01-23 jverzani * man/gWidgets-methods.Rd: fixed entry for font 2008-01-22 jverzani * R/aaaGenerics.R: added gcombobox alias for gdroplist 2007-11-03 John Verzani * R/aaaGenerics.R: added location= argument for gwindow to set initial placement of window 2007-10-23 John Verzani * R/aaaGenerics.R: fixed type with addHandlerChanged 2007-09-18 John Verzani * R/common.R (str2): moved this here to export (was in each toolkit implementation) * R/gvariables.R: added width,height to tbl's in model so that gWidgetsRwxWidgets is happy. 2007-08-14 John Verzani * R/ggenericwidget.R: fixed missing fileurl. 2007-08-13 John Verzani * R/generics.R: trimmed arguments in ggenericwidget 2007-07-31 John Verzani * R/aaaGenerics.R: gwindow -- added args width height to set default size at window creation. Different from size<- which sets the minimum size. 2007-06-26 John Verzani * R/icons.R: Moved icons into gWidgets from tcltk 2007-06-25 John Verzani * R/bbbGenericsANY.R: Added this to handle ANY widgets. Might need some more work. * R/ggenericwidget.R: moved from tcltk into this using gWidgetANY classes. 2007-04-27 John Verzani * R/generics.R: names, as of 2.5.0 does not need set generic 2007-04-23 John Verzani * DESCRIPTION (Package): Changed SaveImage: TRUE to LazyLoad: yes as per suggestion by B. Ripley. gWidgets/.Rinstignore0000644000176000001440000000002612313701404014354 0ustar ripleyusersdoc/auto/.* TODO.txt gWidgets/man/0000755000176000001440000000000012275245147012643 5ustar ripleyusersgWidgets/man/ghtml.Rd0000644000176000001440000000252511462434331014241 0ustar ripleyusers\name{ghtml} \alias{ghtml} \title{Constructors for widgets to handle text input} \description{ The ghtml widget is intended to show HTML text either from a url or from a character string. Currently no toolkits support this widget, although it is in gWidgetsWWW. } \usage{ ghtml(x, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{x}{url or HTML-marked up character string to load into widget.} \item{handler}{(In theory, not implemented yet) Handles a click on a URL. The default is to open the clicked url in the widget. To override, the first argument, a list \code{h}, has component \code{h\$url} containing the url.} \item{action}{ Passed along to the handler as \code{h\$action}} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ This widget loads the given url into a widget. Currently no toolkits support this. The \code{svalue} method returns the current url or character string. The \code{svalue<-} method loads a url or character string in the widget. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ghtml(system.file("html","gedit.html",package="gWidgets"), container = gwindow()) } } \keyword{interface } gWidgets/man/gtext.Rd0000644000176000001440000000603611626242130014256 0ustar ripleyusers\name{gtext} \alias{gtext} \title{Constructor for widget for multi-line editable text input} \description{ The \code{gtext} widget creates a text buffer for handling multiple lines of text. } \usage{ gtext (text = NULL, width = NULL, height = 300, font.attr = NULL, wrap = TRUE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{text}{Initial text in widget} \item{width}{Width of widget in pixels} \item{height}{Height of gtext widget in pixels} \item{font.attr}{Optional specification of font attributes} \item{wrap}{For gtext, are long lines wrapped?} \item{handler}{Handler called when text is changed.} \item{action}{ Passed to handler} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to add method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{gtext} widget has the following methods. The \code{svalue} method returns the text held in the buffer. If \code{drop=TRUE}, then only the text in the currently selection is returned. The \code{svalue<-} method replaces the text in the buffer with the new text. New text is added with the \code{insert} method. The basic usage is \code{insert(obj,text)} where "text" could be a single line or a vector of text, or --for gWidgetsRGtk2 -- a gwidget (although some, like gedit, are kind of flaky). Extra arguments include \code{do.newline} a logical indicating if a new line after the last line should be added (default is \code{TRUE}); \code{font.attr} to specify any font attributes; \code{where} indicating where to add the text (either \code{end} or \code{beginning}). The \code{insert} generic replaces the overused \code{add} for \code{gtext}, but \code{add} will still work. The font can be changed. The \code{font.attr} argument to the constructor is used to specify font properties for the buffer. When specifed to the \code{add} method, the font specification applies to the new text. Both uses use a named character vector to specify the font properties. For instance \code{c(style="normal", weights="bold",sizes="medium")}. The command \code{obj[['tags']]} will produce a list containing all the available attributes. The \code{font<-} method is used to change the font of the currently selected text. It too takes a named character vector specifying the font attributes. If there is no currently selected text, the entire buffer will have the new font attribute. The \code{dispose} method clears the text in the buffer. The \code{addHandlerKeystroke} method for \code{gedit}and \code{gtext} is called for each keystroke. In \code{gtext} or \code{RGtk2} the component \code{key} of the \code{h} argument contains the keystroke. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## gtext example obj <- gtext("First line", container=gwindow()) insert(obj,"second line", font.attr=c(family="monospace")) insert(obj,"third line", font.attr=c(foreground.colors="red")) } } \keyword{interface } gWidgets/man/gbutton.Rd0000644000176000001440000000546512034653527014624 0ustar ripleyusers\name{gbutton} \alias{gbutton} \title{Button constructors} \description{ A button widget is used to present a widget that a user can press to initiate some action. Buttons show text and/or images in a clickable object whose shading indicates that the button is to clicked on. } \usage{ gbutton(text = "", border=TRUE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{text}{Text to show in the button. For buttons, if this text matches a stock icon name, an icon is shown as well. } \item{border}{If \code{TRUE} a border is drawn to make a button look like a button. If \code{FALSE}, the no border so the button looks like a label.} \item{handler}{Handler called on a click event} \item{action}{Either a \code{gaction} instance in which case, the \code{text} and \code{handler} arguments are not used, or is an R object to be passed to the specified handler. } \item{container}{Optional container to attach widget to.} % \item{obj}{a \code{glabel} instance} % \item{angle}{Angle to rotate label, in degrees} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ As buttons are intended to show the user how to initiate some action, they are often labeled as commands. Additionally, if the action is not currently possible given the state of the GUI, a button is typically disabled. This can be done through the \code{enabled} method. The \code{svalue()} method returns the value of the widget. For a button, this is the text as a single string (which may not include a "\\n" for newlines if not supported by the toolkit). The \code{svalue<-} method can be used to set the text of the widget. For buttons, values with length greater than one are pasted together collapsed with "\\n". The \code{addHandlerChanged} method is aliased to the \code{addHandlerClicked} method which can be used to set a handler to respond to click events. When the \code{action} argument is a \code{gaction} instance, then the button label and handler will be derived from the \code{gaction} instance. The \code{enabled<-} method of the \code{gaction} instance should be used to set the sensitivity to user input, not the \code{enabled<-} method of the \code{gbutton} instance. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## button group example w <- gwindow("Button examples") g <- ggroup(container = w) addSpring(g) ## push to right of widget gbutton("help", container = g) addSpace(g, 20) ## some breathing room gbutton("cancel", container = g) gbutton("ok", container = g, handler = function(h, ...) cat("do it\n")) } } \keyword{ interface }% at least one, from doc/KEYWORDS gWidgets/man/ghelp.Rd0000644000176000001440000000435512165556042014235 0ustar ripleyusers\name{ghelp} \alias{ghelp} \alias{ghelpbrowser} \title{Widget to interface with help pages} \description{ A widget to interface with the help pages and that widget placed in a browser. The widget is a notebook capable of showing several pages at once. } \usage{ ghelp(topic = NULL, package = NULL, container = NULL, ..., toolkit = guiToolkit()) ghelpbrowser(title = "Help browser", maxTerms=100, width=1000, height=600, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{topic}{Help topic} \item{package}{Which package to look for topic in} \item{container}{Optional container to attach widget to} \item{title}{Title of help browser} \item{maxTerms}{Maximum number of search responses} \item{width}{Width of browser window in pixels} \item{height}{Height of browser window in pixels} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{ghelp} widget is a notebook to hold help pages. One can add pages with \code{add}. The help page is specified with a character vector or list. The first component is the topic, the second and optional package designation. The \code{svalue} method returns a list with topic and package. The \code{dispose} method will remove the current page. For toolkits that support them, closebuttons appear on the etabs The \code{ghelpbrowser} constructor produces a stand alone GUI for browsing help pages. Unlike other \pkg{gWidgets} constructors, this has no \code{container} argument. } % \value{} % \references{} % \author{} % \note{} \seealso{The \pkg{helpr} package provides a much better interface to R's help pages.} \examples{ \dontrun{ w <- gwindow("Help browser", visible=FALSE) g <- ggroup(horizontal=FALSE, container=w) g1 <- ggroup(container=g) addSpring(g1) glabel("Help on:", container=g1) e <- gedit("", container=g1) helpWidget <- ghelp(container = g, expand=TRUE) addHandlerChanged(e, handler=function(h,...) { add(helpWidget, svalue(h$obj)) }) visible(w) <- TRUE ## add others add(helpWidget,"base:::mean") add(helpWidget, list(topic="mean", package="base")) add(helpWidget, "boxplot") } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-icons.Rd0000644000176000001440000000240011406427005016002 0ustar ripleyusers\name{gWidgets-icons} \alias{gWidgets-icons} \alias{addStockIcons} \alias{getStockIcons} \alias{stockIconFromClass} \alias{stockIconFromObject} \alias{.addStockIcons,ANY-method} \alias{.getStockIcons,ANY-method} \alias{.stockIconFromClass,ANY-method} \alias{.stockIconFromObject,ANY-method} \title{Functions for adding icons} \description{ Two functions for listing "stock" icons, and adding "stock" icons. A stock icon can be referenced within gWidgets by its simple name, such as "ok" or "close". } \usage{ addStockIcons(iconNames, iconFiles, ...,toolkit=guiToolkit()) getStockIcons(..., toolkit=guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{iconNames}{A vector of icon names} \item{iconFiles}{A matching vector of filenames for the icons} \item{...}{ignored} \item{toolkit}{Which toolkit to use} } \details{ The file type must be supported by the toolkit. The \code{tcltk} supports few filetypes without additional libraries. } % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ iconNames <- c("larrow","rarrow") iconFiles <= c("/usr/share/icons/larrow.png", "/usr/share/icons/rarrow.png") addStockIcons(iconNames, iconFiles) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gstatusbar.Rd0000644000176000001440000000244212034653372015307 0ustar ripleyusers\name{gstatusbar} \alias{gstatusbar} \title{Constructor of status bar widget} \description{ A status bar widget is used to send message to the user. A familiar instance is the bottom area of a web browser. } \usage{ gstatusbar(text = "", container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{text}{Initial text of status bar} \item{container}{Optional container to attach widget to. Should be \code{gwindow} object} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The status bar simply shows a message in a label, typically at the bottom of a window. The \code{svalue} and \code{svalue<-} methods can be used to query or set the text. message onto the stack. Statusbars should be added to the top-level gwindow instance. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ w <- gwindow("status bar example") tbl <- list(quit=list(icon="quit", handler = function(...) dispose(w))) tb <- gtoolbar(tbl, container=w) sb <- gstatusbar("", container=w) txt <- gtext("type here", container=w) addHandlerChanged(txt, handler=function(h,...) svalue(sb) <- paste("You typed",svalue(txt),"in the box",collapse=" ")) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gcombobox.Rd0000644000176000001440000000736612034653205015114 0ustar ripleyusers\name{gcombobox} \alias{gcombobox} \alias{gdroplist} \alias{[<-,gCombobox-method} \title{Widgets to allow selection from a vector of items} \description{ A combobox allows selection of a value from a list of items using a popup menu. Additionally, the widget can combine a text entry widget for user input outside of the pre-set list of items. A combobox is useful for selection from a moderate size of items (2-30, say). For smaller sets of items, a radio button group is a possibility, for larger sets of items, a scrollable (and perhaps searchable) table may be preferred. } \usage{ gcombobox(items, selected = 1, editable = FALSE, coerce.with=NULL, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) gdroplist(items, selected = 1, editable = FALSE, coerce.with=NULL, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{items}{ Vector of values to select from. This may also be a data frame, in which case the first column is the vector of values, the second (if present) indicates a stock icon to display with the item (not all toolkits), and the third (if present) will indicate a tooltip to display (not all toolkits). } \item{selected}{ For gradio the initial selected value (as an index) For a drop list, the first selected value. Use 0 to leave blank} \item{editable}{A logical indicating if the user can add an entry to the list of available answers} \item{coerce.with}{Apply this function to selected value before returning} \item{handler}{Called when selection is changed} \item{action}{Passed to handler when called.} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The initial \code{items} can be a vector or a data frame. Not all tool kits do something with the extra columns in the data frame. The \code{svalue} method returns the selected value by name. Assume the value is a character vector. Use the \code{coerce.with} argument to return a value of a different type. If the extra argument \code{index=TRUE} is specified, the index of the selected value is given. The \code{svalue<-} method can be used to set the selected value. This is done my name or if the argument \code{index=TRUE} is given by index. The value can be a data frame, in which case the first column is used to match against the current items. The \code{"["} method refers to the vector defining the items. The \code{"[<-"} method can be used to change the vector defining the items. The \code{"length"} method returns the number of items. For \code{gcombobox} the argument \code{editable=TRUE} adds a text-edit box where the user can type in a selection. By default this value is returned as a character by \code{svalue}. Use \code{coerce.with} to coerce this prior to returning. } % \value{} % \references{} % \author{} % \note{} \seealso{ A combobox is one of several ways to select a value of a set of items. See also \code{\link{gcheckbox}}, \code{\link{gradio}}, \code{\link{gcheckboxgroup}}, and \code{\link{gtable}}. Methods for gComponent objects are detailed in \code{\link{gWidgets-methods}}. Event Handlers are detailed in \code{\link{gWidgets-handlers}}. } \examples{ \dontrun{ flavors <- c("vanilla", "chocolate", "strawberry") f <- function(h,...) print( paste("Yum", paste(svalue(h$obj),collapse=" and "), sep = " ")) w <- gwindow("combobox example") gp <- ggroup(container=w) glabel("Favorite flavor:", container=gp) cb <- gcombobox(flavors, editable=TRUE, container=gp, handler=f) svalue(cb) <- "vanilla" svalue(cb) cbg[3] <- "raspberry" } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gvarbrowser.Rd0000644000176000001440000000241311406427005015463 0ustar ripleyusers\name{gvarbrowser} \alias{gvarbrowser} \title{Widget for browsing environment} \description{ A widget to browse the objects in the current global environment } \usage{ gvarbrowser(handler = NULL, action = "summary", container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{handler}{Handler for double click. Default is to call value of \code{action} on the object} \item{action}{Passed to handler.} \item{container}{Optional container to attach widget to} \item{\dots}{ignored} \item{toolkit}{Which GUI toolkit to use} } \details{ In gWidgetsRGtk2 there is an idle handler that updates the top-level components. However, changes are made below this, they will not be updated automatically. Rather, the user must close and expand that level. The handler is called on the widget that provides the display, and not the gvarbrowser widget. If you want that in the handler, be sure to pass it in via the action argument. svalue returns a character string containing the selected variable. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ gvarbrowser(container=TRUE) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gtree.Rd0000644000176000001440000001700212106531574014233 0ustar ripleyusers\name{gtree} \alias{gtree} \title{Constructor for widget to display heirarchical dta} \description{ This widget allows tree-like data to be presented. Each node on the tree should be a data frame with the same column structure. The first column is treated like a key, and should be unique. Offspring are specified through a function of the keys which are ancestors. This function returns the data frame to be displayed. Values in the tree can be selected with the mouse. This value can be retrieved through a method, or a handler can be assigned to double click events. } \usage{ gtree(offspring = NULL, hasOffspring = NULL, offspring.data = NULL, col.types = NULL, icon.FUN = NULL, chosencol = 1, multiple = FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{offspring}{A function to produce a data frame. The first column of the data frame is used as a key. It should be unique, otherwise the updating will not work properly. The \code{offspring} function has two arguments, the first being the path (the first column of the offspring data frame is the key, and the path is the vector of keys) and the value of \code{offspring.data}. The data frame can determine whether an entry has offspring, by having the second column be a logical vector, \code{TRUE} if there is offspring, \code{FALSE} if not. } \item{hasOffspring }{ Whether an entry has an offspring is determined by a. if this function is non-\code{NULL} and it returns a \code{TRUE} value when called on the offspring data frame for this row, b. if this is NULL and the second column of the offspring data frame is a logical vector and for this row is \code{TRUE}. If this function is \code{NULL} and the second column is not a logical vector then it is assumed that there are no offspring. } \item{offspring.data}{Passed to \code{offspring} function to parameterize that function.} \item{col.types}{Used to determine the type of column, given as a data frame with 1 or more rows. Otherwise it is determined by first row of offspring data frame. If the offspring function can return an empty data frame, then this argument should be given.} \item{icon.FUN}{An optional function to determine an icon place into the first column. This function gets called with the data in \code{offspring}, and should return a row vector of length \code{nrow(offspring)}. The icons are stock icons, and should be referenced by name. The helper function \code{getStockIcons} list all the available stock icons.} \item{chosencol}{The column used when requesting the selected row's value. Defaults to first} \item{multiple}{ A logical to determine if multiple selection is allowed. Defaults to \code{FALSE}} \item{handler}{ Handler for double click events} \item{action}{ Passed to handler } \item{container}{Optional container to attach widget to.} \item{...}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ In an abstract sense, these trees are specified by a function which produces the value at a given node from the ancestry of the given node, and a function specifying if a node has offspring. The \code{offspring} function determines the displayed data for a certain node. It has signature \code{(path, offspring.data)}, where the path consists of the ancestors and \code{offspring.data} is an optional value passed in when the tree object is constructed. This function returns a data frame. Its first column should consist of unique values, as it is treated like a key. The \code{hasOffspring} function is called on the return value of \code{offspring}. It should return a logical indicating which rows have offspring. If this argument is not present, then the second column of the return values of \code{offspring} are consulted. If these are logical, then they are used to determine if offspring are present. Otherwise, no offspring are assumed. The \code{icon.FUN} function is called on the return value of \code{offspring}. If present, it should return a vector of stock icon names. The \code{svalue} method returns the current key. The \code{index} argument has changed. If \code{index} is \code{TRUE}, the path of each selection is returned as a numeric vector, where the numbers represent the sibling count at each level, 1-based. That is \code{c(1,2,3)} is the 3rd offspring of the second offspring of the first offspring of the root. If more than one selection is made, then a list of such values is returned. This way -- in theory -- we can set values by index too. In particular, we should have \code{svalue(obj, index=TRUE) <- svalue(obj, index=TRUE)}. (Before, using a numeric value for index would give the ith column, as opposed to the chosen column. This behaviour can be found using the \code{"["} method.) The \code{"["} method refers to the vector of keys for the selected object. That is, svalue gives the current key, and \code{[} returns the path of keys. The \code{addHandlerDoubleclick} handler (also \code{addHandlerChanged}) can be set to respond to a double click event. The \code{addHandlerClicked} handler should be called when the selection is changed. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## function to find offspring offspring <- function(path, offspring.data=NULL) { if(length(path) > 0) directory <- paste(getwd(), .Platform$file.sep, paste(path,collapse=.Platform$file.sep), sep="") else directory <- getwd() files <- file.info(dir(path=directory, full.names=TRUE))[,c(1,2,3)] files <- data.frame(filename=dir(path=directory), isdir=files[,2], size=as.integer(files[,1]), mode=as.character(files[,3]), stringsAsFactors=FALSE) return(files) } hasOffspring <- function(children,offspring.data=NULL, ...) { return(children$isdir) } icon.FUN <- function(children,offspring.data=NULL, ...) { x <- rep("file", length=nrow(children)) x[children$isdir] <- "directory" return(x) } ## shows isdir directory, as hasOffspring is specified w <- gwindow("test with isdir showing") gtree(offspring, hasOffspring, icon.FUN = icon.FUN, container=w) ## does not show isdir directory, as hasOffspring=NULL and ## second column is a logical w <- gwindow("tree test no dir column") tr <- gtree(offspring, hasOffspring=NULL, icon.FUN = icon.FUN, container=w) ## Show a fixed list using a dynamic tree l <- list(a=list( aa=1, ab=2, ac=list(ac1=1) ), b=list( ba=list( baa=1, bab=list( baba=1 ) ) )) offspring <- function(path, ...) { print(path) ll <- l if(length(path) > 0) { for(i in path) ll <- ll[[i]] } out <- data.frame(name=names(ll), hasOffspring=!sapply(ll, is.atomic), value=as.character(sapply(ll, function(i) ifelse(is.atomic(i), i, ""))), stringsAsFactors=FALSE) out } w <- gwindow("Tree from list") tr <- gtree(offspring=offspring, container=w) addHandlerDoubleclick(tr, handler=function(h,...) { print(svalue(h$obj)) # the key print(h$obj[]) # vector of keys }) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-undocumented.Rd0000644000176000001440000000554211454602375017403 0ustar ripleyusers\name{gWidgets-undocumented} \alias{gWidgets-undocumented.Rd} \alias{show,guiWidget-method} \alias{editFormulaDialog} \alias{editSelectDialog} \alias{editSubsetDialog} \alias{.fixFontMessUp} %% screwed this up. \alias{str2} \alias{gwCat} % for error messages %% These from the ANY class for compound widgets \alias{.add,ANY,ANY,gWidgetANY-method} \alias{.add,gHelpANY,ANY,character-method} \alias{.add,gHelpANY,ANY,list-method} \alias{.add,gHelpANY-method} \alias{add,ANY-method} \alias{[<-,gWidgetANY-method} \alias{[,gWidgetANY-method} \alias{[,gCommandlineANY-method} \alias{dimnames<-,gWidgetANY-method} \alias{dimnames,gWidgetANY-method} \alias{.dispose,gHelpANY-method} \alias{enabled<-,gWidgetANY-method} \alias{enabled,gWidgetANY-method} \alias{focus<-,gWidgetANY-method} \alias{focus,gWidgetANY-method} \alias{font<-,gWidgetANY-method} \alias{.gcommandline,ANY-method} \alias{.ggenericwidget,ANY-method} \alias{.ghelpbrowser,ANY-method} \alias{.ghelp,ANY-method} \alias{.leftBracket,gCommandlineANY-method} \alias{.length,gHelpANY-method} \alias{names<-,gWidgetANY-method} \alias{names,gWidgetANY-method} \alias{.size,gHelpbrowserANY-method} \alias{size<-,gWidgetANY-method} \alias{.size<-,gHelpbrowserANY,ANY,numeric-method} \alias{.svalue<-,gCommandlineANY-method} \alias{.svalue<-,gAddargANY-method} \alias{.svalue<-,gBivariateANY-method} \alias{.svalue<-,gModelANY-method} \alias{.svalue,character-method} \alias{.svalue,gCommandlineANY-method} \alias{.svalue,gGenericWidgetANY-method} \alias{.svalue,gHelpANY-method} \alias{.svalue,gAddargANY-method} \alias{.svalue,gUnivariateANY-method} \alias{.svalue,gUnivariateTableANY-method} \alias{.svalue,gFileURLANY-method} \alias{.svalue,gBivariateANY-method} \alias{.svalue,gModelANY-method} \alias{.svalue,gLmerANY-method} \alias{svalue<-,gWidgetANY-method} \alias{svalue,numeric-method} \alias{svalue,character-method} \alias{svalue,gWidgetANY-method} \alias{.tag<-,guiWidget-method} \alias{.tag<-,gWidgetANY-method} \alias{.tag,guiWidget-method} \alias{.tag,gWidgetANY-method} \alias{tag<-,gWidgetANY-method} \alias{tag,gWidgetANY-method} \alias{update,gWidgetANY-method} \alias{visible<-,gWidgetANY-method} \alias{visible,gWidgetANY-method} \alias{.visible<-,gHelpbrowserANY,ANY,logical-method} \alias{isExtant,gWidgetANY-method} \alias{.gsvg,ANY-method} \alias{.redo,guiWidget-method} \alias{.redo,gWidgetANY-method} \alias{.svalue,NULL-method} \alias{.toolkitProvidesWidget,ANY-method} \alias{.undo,guiWidget-method} \alias{.undo,gWidgetANY-method} \alias{.gformlayout,ANY-method} \alias{.leftBracket,gFormLayoutANY-method} \alias{.names,gFormLayoutANY-method} \alias{.svalue,gFormLayoutANY-method} \alias{[,gFormLayoutANY-method} %% these from ANY methods \title{Undocumented, but exported, functions} \description{Undocumented, but exported functions from gWidgets.} \keyword{interface}% at least one, from doc/KEYWORDS \keyword{internal}gWidgets/man/gradio.Rd0000644000176000001440000000507112034653335014375 0ustar ripleyusers\name{gradio} \alias{gradio} \alias{[<-,gRadio-method} \title{Radio button group widget} \description{ A radio group allows the user to select one value from a set of items. The items may be displayed horizontally or vertically. } \usage{ gradio(items, selected = 1, horizontal = FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{items}{ Vector of values to select from } \item{selected}{ The initial selected value (as an index). Radio groups must have a selection} \item{horizontal}{A logical specifying the layout for gradio} \item{handler}{Called when selection is changed} \item{action}{Passed to handler when called.} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue} method returns the selected value by name. If the extra argument \code{index=TRUE} is specified, the index of the selected value is given. The \code{svalue<-} method can be used to set the selected value. One can specify the value by name or by index if \code{index=TRUE} is specified. The \code{"["} method refers to the vector defining the items. The \code{"[<-"} method can be used to change the vector defining the items. The \code{"length"} method returns the number of items. } % \value{} % \references{} % \author{} % \note{} \seealso{ The radio group is one of several widgets useful to selecting a value or values from a set of items. See also \code{\link{gcheckbox}}, \code{\link{gcheckboxgroup}}, \code{\link{gcombobox}}, and \code{\link{gtable}} Methods for gComponent objects are detailed in \code{\link{gWidgets-methods}}. Event Handlers are detailed in \code{\link{gWidgets-handlers}}. } \examples{ \dontrun{ flavors <- c("vanilla", "chocolate", "strawberry") w <- gwindow("Radio example", visible=FALSE) gp <- ggroup(container=w) glabel("Favorite flavor:",container=gp, anchor=c(0,1)) rb <- gradio(flavors, container=gp) addHandlerClicked(rb, handler=function(h,..) { cat(sprintf("You picked \%s\n", svalue(h$obj))) }) visible(w) <- TRUE betterFlavors <- c("coffee", "mint chip") rb[] <- betterFlavors rb[] <- c(betterFlavors, "chocolate") # some toolkits don't allow change of length rb[3] <- "mango sorbet" ## can change a label name ## set values svalue(rb) <- "coffee" ## by name svalue(rb, index=TRUE) <- 1 ## by index ## get selected values svalue(rb) svalue(rb, index=TRUE) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/ggroup.Rd0000644000176000001440000001621112165556030014430 0ustar ripleyusers\name{ggroup} \alias{ggroup} \alias{gframe} \alias{gexpandgroup} \title{Box containers for packing in subsequent widgets} \description{ Various box containers useful for laying out GUI controls. These containers pack in child widgets from left to right or top to bottom. A few arguments can be used to adjust the sizing and positioning. } \usage{ ggroup(horizontal = TRUE, spacing = 5, use.scrollwindow = FALSE, container = NULL, ..., toolkit = guiToolkit()) gframe(text = "", markup = FALSE, pos = 0, horizontal=TRUE, container = NULL, ..., toolkit = guiToolkit()) gexpandgroup(text = "", markup = FALSE, horizontal=TRUE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{horizontal}{Specifies if widgets are packed in left to right or top to bottom (\code{FALSE})} \item{spacing}{Space in pixels around each widget. Can be changed with \code{svalue}} \item{text}{Text for label} \item{markup}{Optional markup. (See \code{\link{glabel}} for details.)} \item{pos}{Where to place label: 0 is to left, 1 to right, interpolates.} \item{handler}{Called when expand arrow is clicked} \item{action}{Passed to handler} \item{use.scrollwindow}{If \code{TRUE} then group is placed in a scrollwindow allowing panning with mouse.} \item{container}{Optional container to attach widget to. Not optional for gWidgetstcltk, or gWidgetsRwxwidgets} \item{\dots}{Passed to the \code{add} method of the container} \item{toolkit}{Which GUI toolkit to use} } \details{ A \code{ggroup} is the primary container for packing in subsequent widgets, either from left to right or top to bottom. Widgets are packed in using the \code{add} method and can be removed with the \code{delete} method. The \code{gframe} container adds a decorative border and optional label to the box container. The \code{gexpandgroup} containers has an optional label and a trigger to click on which toggles the display of the the child widgets. By default, the child widgets are not shown. Using the \code{visible<-} method to adjust. The containers pack in child widgets from either left to right (when \code{horizontal=TRUE}) or from top to bottom (when \code{horizontal=FALSE}). Child widgets are added to box containers through their \code{add} method or through the containers use as the parent container when a widget is constructed. This is done by using the \code{container} argument of the widget. The \code{container} argument is not optional for \pkg{gWidgetstcltk}. It is suggested that it always be included for portability. When it is not included, widgets are added to the new group object through its \code{add} method. Otherwise, when a widget is created, the group is specified as the container and the add method is then called implicitly, with the constructor's \code{...} argument used to pass arguments to \code{add}. When the parent allocates space to a child widget it be possible to allocate more space than is requested by the child widget. The child may then be positioned in the available space by specifying the \code{anchor=c(a,b)} argument to \code{add} where \code{a} and \code{b} are values in -1,0,1 and specify the position using Cartesian coordinates. If the argument \code{expand=TRUE} to \code{add} is given, then the space available to the child expands. The child widget can be instructed to grow to fill the space. The \code{add} method's argument \code{fill}, with values \code{"both"}, \code{"x"}, \code{"y"} or \code{""}, instructs the child as to which direction to grow in. (The \code{""} value says none.) The implementation of \code{expand}, \code{anchor}, \code{fill} varies with the underlying toolkit. The basic language comes from \pkg{tcltk} and an attempt -- not entirely successful -- is made to implement it in the \pkg{gWidgetsRGtk2} and \pkg{gWidgetsQt} packages. A child component may be deleted using \code{delete(parent, child)}. TYpically the child may be replaced in the GUI, using \code{add}. The \code{spacing} argument determines the number of pixels of padding between each widget when packed in. This can be set when the group is constructed, or later using \code{svalue<-}. The argument \code{use.scrollwindow = TRUE} will add scrollbars around the box container. When the child components require more size than is given to the container, the scroll bars allow one to position the viewable area over the child of interest. Again, not all toolkits do this equally well. To put space between two adjoining widgets, the \code{addSpace(obj, value, ...)} method may be used where \code{value} is the number of pixels of padding between the just packed widget, and the next one to be packed. The \code{addSpring(obj,...)} method will push the just packed widget and the next-to-be packed widget as far apart as possible. For \code{ggroup}, in \code{gWidgetsRGtk2} a few arguments add to the container. The argument \code{raise.on.dragmotion = TRUE} will cause the group to jump to the foreground when a drag action crosses it. For \code{gframe} and \code{gexpandgroup} the label name can be retrieved or adjusted with the \code{names} method. For \code{gframe} and \code{gexpandgroup} the label can be adjusted through the \code{names<-} method. For \code{gexpandgroup} the \code{visible} method can be used to toggle the display programmatically. } % \value{} % \references{} % \author{} % \note{ } \seealso{For top-level containers \code{\link{gwindow}}, for containers to display more than one child widget see \code{\link{gpanedgroup}}, \code{\link{gnotebook}}, \code{\link{glayout}}} \examples{ \dontrun{ ## basic group group <- ggroup(horizontal=FALSE, container=gwindow()) l <- glabel("widget 1") ## not in gWidgetstcltk -- needs a container add(group, l) glabel("widget 2", container = group) ## style for all toolkits ## nested groups group <- ggroup(horizontal=FALSE, container=gwindow()) innergroup <- ggroup(container = group) gtext("Text area", container=group) gbutton("button 1", container = innergroup) gbutton("button 2", container = innergroup) ## expand argument group <- ggroup(horizontal=FALSE, container=gwindow()) gbutton("no expand", container=group) gbutton("expand=TRUE", container=group, expand=TRUE) ## anchor argument w <- gwindow("Anchor") size(w) <- c(500,500) group <- ggroup(container=w) glabel("upper left", container=group, anchor=c(-1,1)) glabel("lower right", container=group, anchor=c(1,-1)) ## add spring group <- ggroup(container=gwindow("menubar-like example")) gbutton("File",handler=function(h,...) print("file"), container=group) gbutton("Edit",handler=function(h,...) print("edit"), container=group) addSpring(group) gbutton("Help",handler=function(h,...) print("help"), container=group) ## delete and add w <- gwindow("Delete and add", visible=FALSE) g <- ggroup(container=w) b <- gcheckbox("hide", checked=FALSE, container=g) l <- gedit("click checkbox to hide me", container=g) addHandlerClicked(b, handler=function(h,...) { if(svalue(b)) delete(g, l) else add(g, l) }) visible(w) <- TRUE } } \keyword{ interface } gWidgets/man/guiToolkit.Rd0000644000176000001440000000274711617600601015263 0ustar ripleyusers\name{guiToolkit} \alias{guiToolkit} \alias{gtoolkit} \alias{guiWidgetsToolkit-class} \alias{guiWidgetsToolkitRGtk2-class} \alias{guiWidgetsToolkitrJava-class} \alias{guiWidgetsToolkitSJava-class} \alias{guiWidgetsToolkittcltk-class} \alias{guiWidgetsToolkitRwxWidgets-class} \title{Function to select the GUI toolkit used by gWidgets} \description{ A GUI toolkit is a separate package that implements the gWidgets API. This function allows one to select the toolkit to be used by default. } \usage{ guiToolkit(name = NULL) gtoolkit() } %- maybe also 'usage' for other objects documented here. \arguments{ \item{name}{The name matches the package name without the initial gWidgets. For instance, "RGtk2" refers to the implementation provided by gWidgetsRGtk2.} } \details{ Toolkits are named gWidgetsXXX. This function is used to get the toolkit class, or have the user select one. The \code{gtoolkit} function returns a string form of the toolkit. One way to set a toolkit is to use the \code{guiToolkit} option, as in \code{options(guiToolkit="RGtk2")}. } \value{ The \code{guiToolkit} function returns a subclass of guiWidgetsToolkit that is used for dispatching purposes by gWidgets. For example, the method svalue dispatches on its first argument and the value of the toolkit class stored in the toolkit slot of the object. The \code{gtoolkit} function returns a character string for the toolkit. } \examples{ guiToolkit("RGtk2") } \keyword{ interface }% at least one, from doc/KEYWORDS gWidgets/man/gtable.Rd0000644000176000001440000001471012165556302014367 0ustar ripleyusers\name{gtable} \alias{gtable} \title{Constructor for widget to display tabular data} \description{ This widget displays either a vector, matrix or data frame in a tabular format. The main usage is for user selection of a row or rows. } \usage{ gtable(items, multiple = FALSE, chosencol = 1, icon.FUN = NULL, filter.column = NULL, filter.labels = NULL, filter.FUN = NULL, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{items}{A vector, matrix or data frame to be displayed. A vector and matrix is coerced into a data frame.} \item{multiple}{A logical. If \code{TRUE} multiple lines can be selected} \item{chosencol}{By default, only the value in this column is returned by the \code{svalue} method.} \item{icon.FUN}{If given, this function is applied to the data frame to be shown. It should return a vector of stock icon names} \item{filter.column}{If not \code{NULL} a filter by droplist is given which can be used to filter the displayed values shown using the values in this column.} \item{filter.labels}{If more complex filtering is desired then this argument populates the values of the combobox and the \code{filter.FUN} argument is used to specify a function to interpret these values.} \item{filter.FUN}{Either a function with signature \code{(obj, filter.by)} to specify a vector of logical values indicating which rows should be shown or the character "manual" in which filtering is done directly through the \code{visible} method and not through a popup box} \item{handler}{Called on a double click event} \item{action}{Passed to handler} \item{container}{Optional container to attach widget to} \item{\dots}{ ignored } \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue} method returns the selected value(s). By default, only the value(s) in the chosen column are returned. Use the argument \code{drop=FALSE} to return the entire row. To return the row index, use the argument \code{index=TRUE}. This index refers to the whole data store, not just the visible portion when filtering is being used. The \code{"["} notion treats the object like a data frame. When filtering, this notation refers to the entire data frame, not the visible data frame. The comment about the returned index by \code{svalue} can be described by the fact that \code{obj[svalue(obj,index=TRUE), ]} should be the same value as \code{svalue(obj)}. Assignment via \code{"[<-"} is possible with limitations imposed by the toolkits. The graphical display of tabular matter is usually done, similar to data frames, in terms of columns each having the same type. For some toolkits, all values are converted to characters, for others, the type must be maintained. In R, coercion of types may occur when assigning to a data frame, but this won't be so with the underlying toolkit widget. To be portable across toolkits, the column type should not change during assignment, nor should the number of rows be reduced. In particular, assignment with \code{"[<-"} for factors can cause warnings if the values are not in the factor's levels. When the value being assigned is a matrix there is a coercion to a data frame which may change the type. The \code{visible} and \code{visible<-} methods refer to which rows of the data store are visible in the widget. These are specified by a vector of class logical. This may be used when there is filtering, not sorting. The value returned by \code{svalue} is a logical vector of length given by the number of rows of the data store, with \code{TRUE} indicating that the row is displayed. When setting the visibility of a row through \code{svalue} the vector of values should have the same length as the number of rows, otherwise recycling occurs. (So \code{visible(obj) <- TRUE} will work to display all the rows.) The \code{length} method returns the length of the underlying data store. The \code{dim} method returns the dimension of the underlying data store. The \code{names} method returns the names of the underlying data store. The \code{names<-} method can be used to set the names of the underlying data store and the values displayed in the column headers of the widget. Row names are ignored in the display of this widget. A single click is used for selection of a value. The \code{addHandlerDoubleclick} handler can be used to define a callback to respond to a double click event. } % \value{} % \references{} % \author{} \seealso{See also \code{\link{gtree}} for displaying tree-like data and \code{\link{gdf}} for tabular data meant to be edited } \examples{ \dontrun{ ## example to select CRAN mirror m <- getCRANmirrors()[,c(1,4)] setCRAN <- function(URL) { ## see chooseCRANmirror repos = getOption("repos") repos["CRAN"] <- gsub("/$", "", URL) options(repos=repos) } w <- gwindow("gtable example",width=400) gp <- ggroup(horizontal=FALSE, container=w) tab <- gtable(m, chosencol = 2, container=gp, expand=TRUE, handler = function(h,...) setCRAN(svalue(h$obj))) bg <- ggroup(container=gp) addSpring(bg) gbutton("dismiss", container=bg, handler = function(h,...) dispose(w)) ## an example with icons. ## Select variables from a data frame ## find icons by class icon.FUN <- function(items) { dfName <- svalue(cb) df <- try(get(dfName, envir=.GlobalEnv), silent=TRUE) if(inherits(df,"try-error")) return(rep(NULL,dim(items)[1])) if(is.data.frame(items)) items <- items[,1, drop=TRUE] sapply(items, function(i) { class(df[,i])[1] }) } ## list data frames in an environment lsDF <- function(envir=.GlobalEnv) { varNames <- ls(envir=envir) dfs <- sapply(varNames, function(i) inherits(get(i,envir=envir),"data.frame")) varNames[dfs] } ## set up GUI w <- gwindow("Select variables",width=250) g <- ggroup(horizontal=FALSE, container=w) l <- glabel("Data frame", container=g) cb <- gcombobox(lsDF(), container=g) blankDF = data.frame(variables=character(0), stringsAsFactors=FALSE) tbl <- gtable(blankDF, icon.FUN=icon.FUN, container=g, expand=TRUE) ## add handlers addHandlerChanged(cb, handler <- function(h,...) { dfName <- svalue(h$obj) dfNames <- names(get(dfName,envir=.GlobalEnv)) tbl[,] <- data.frame(variables=dfNames, stringsAsFactors=FALSE) }) addHandlerClicked(tbl, handler = function(h,...) { cat("Do something with",svalue(cb),"::", svalue(h$obj),"\n") }) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-handlers.Rd0000644000176000001440000002311112034653146016476 0ustar ripleyusers\name{gWidgets-handlers} \alias{gWidgets-handlers} \alias{removehandler} \alias{addhandlerchanged} \alias{addhandlerkeystroke} \alias{addhandlerclicked} \alias{addhandlerdoubleclick} \alias{addhandlerrightclick} \alias{addhandlerfocus} \alias{addhandlerblur} \alias{addhandlerexpose} \alias{addhandlermousemotion} \alias{addhandlerunrealize} \alias{addhandlerdestroy} \alias{addhandleridle} \alias{addpopupmenu} \alias{add3rdmousepopupmenu} \alias{addhandler} \alias{addHandler} \alias{removeHandler} \alias{blockHandler} \alias{unblockHandler} \alias{addHandlerChanged} \alias{addHandlerKeystroke} \alias{addHandlerClicked} \alias{addHandlerDoubleclick} \alias{addHandlerRightclick} \alias{addHandlerFocus} \alias{addHandlerBlur} \alias{addHandlerMouseMotion} \alias{addHandlerExpose} \alias{addHandlerUnrealize} \alias{addHandlerDestroy} \alias{addHandlerIdle} \alias{addHandlerColumnClicked} \alias{addhandlercolumnclicked} \alias{addHandlerColumnRightclick} \alias{addhandlercolumnrightclick} \alias{addHandlerColumnDoubleclick} \alias{addhandlercolumndoubleclick} \alias{addPopupmenu} \alias{add3rdMousePopupmenu} \alias{removeHandler} \title{Methods to add event handlers to objects} \description{ In the gWidgets API handlers are called in reponse to certain events such as keystrokes or clicks. This set of methods makes a consistent interface to some typical events. Not all handlers are defined for each widget. } \usage{ addHandlerChanged(obj, handler = NULL, action = NULL, ...) addHandlerKeystroke(obj, handler = NULL, action = NULL, ...) addHandlerClicked(obj, handler = NULL, action = NULL, ...) addHandlerDoubleclick(obj, handler = NULL, action = NULL, ...) addHandlerRightclick(obj, handler = NULL, action = NULL, ...) addHandlerFocus(obj, handler = NULL, action = NULL, ...) addHandlerBlur(obj, handler = NULL, action = NULL, ...) addHandlerMouseMotion(obj, handler = NULL, action = NULL, ...) addHandlerExpose(obj, handler = NULL, action = NULL, ...) addHandlerUnrealize(obj, handler = NULL, action = NULL, ...) addHandlerDestroy(obj, handler = NULL, action = NULL, ...) addHandlerIdle (obj, handler = NULL, action = NULL, interval = 1000, ...) addPopupmenu(obj, menulist, action=NULL, ...) add3rdMousePopupmenu(obj, menulist, action=NULL, ...) %%addHandler(obj, signal, handler = NULL, action = NULL, ...) removeHandler(obj, ID=NULL, ...) blockHandler(obj, ID=NULL, ...) unblockHandler(obj, ID=NULL, ...) } \arguments{ \item{obj}{The object to assign handler to} %% \item{signal}{The signal the handler responds to} \item{handler}{A function to call if the given event occurs. The function's first argument is a list with some specific components. The component \code{obj} contains the object that the handler was assigned to. The \code{action} component contains the value given to the argument \code{action}. This can be used with \code{do.call} to make simple handlers. Or, this can be used to pass in other widgets, etc. Sometimes there are other components. For drag and drop handlers the component \code{dropdata} refers to the dropped data. For \code{ggraphics} the \code{addHandlerclicked} contains components \code{x} and \code{y} indicating where the click occurred. } \item{action}{Used to pass extra information into handlers } \item{interval}{For \code{addHandleridle} this specifies the time in milliseconds between calls to the handler.} \item{menulist}{For \code{addpopupmenu} and \code{add3rdmousepopupmenu} this specifies a menubar using a list which is in turn passed to \code{gmenu}.} \item{ID}{When a handler is assigned, an id is returned. This id can be used to remove or block a handler from an object.} \item{...}{Not documented, currently has no role.} } \details{ At first these handlers were all lowercase. These functions are still availabe, although the mixed case usage is encouraged In GTK, and other toolkits, an event causes a signal to be triggered and these handlers are called in response to that signal. These signals have various names known to the GTK programmer. say. These functions attempt to shield the gWidgets user from needing to learn these signals. For gWidgetsRGtk, if these handlers prove insufficient then the non-exported \code{addHandler} function has an additional \code{signal} argument: \code{(obj,signal,handler, action,...)} for specifying a GTK signal. By avoiding this, we can make the gWidgets API non-toolkit specific. The signals are defined to match the event described by the method name, e.g., "doubleclick." The handlers all have signature \code{(h,...)} where the first argument is a list with components \code{obj} containing the widget the handler is added to and \code{action} containing the values passed along to the \code{action} argument. This can be used to pass in other widget's names, when they can not be found from a function closure, say. The handlers do not have lazy evaluation. The value of \code{action} is the one at the time of creation of the widget. (See the example). In GTK, a means to cheat this is to pass in a gWidget instance, as the underlying GTK objects are stored as pointers, not copies, so that when queried, their current state is used. \describe{ \item{\code{addHandlerChanged}:}{ This handler is called when a widget is "changed." This is interpreted differently by the various widgets. For \code{gedit} change refers to a changed value, not a keystroke change (when ENTER is pressed). For notebooks, this is called when a page is changed. } \item{\code{addHandlerKeystroke}:}{ This handler is called when keys are pressed in the text widgets. The extra argument \code{key} is used to pass back the key code of the pressed key. } \item{\code{addHandlerClicked}:}{This handler is called when a widget, such as a button or label, is clicked. } \item{\code{addHandlerDoubleclick}:}{This handler is called when a widget is doubleclicked, like in the tree widget. Not all widgets receive a double click signal. Only when a single mouse click is needed for selection is this implemented.} \item{\code{addHandlerRightclick}:}{This handler is called when a widget is clicked with the right mouse button} \item{\code{addHandlerFocus}:}{This handler is called when a widget gains focus} \item{\code{addHandlerBlur}:}{This handler is called when a widget loses focus} \item{\code{addHandlerMouseMotion}:}{This handler is called when a the mouse moves over a widget. In some toolkits it is called just once per visit to the widget, for others maybe multiple times. This is like a mouseover for web pages. The drag motion handler is similar, only it is called when a drag event is dragged over a widget.} \item{ \code{addHandlerExpose}:}{ handler is called when a widget is exposed. For instance when a page in a notebook is exposed.} \item{ \code{addHandlerUnrealize}:}{ handler is called when a widget is being unrealized.} \item{ \code{addHandlerDestroy}:}{ handler is called when a widget is being destroyed. For top level windows, this usually allows one to intercept the window destroy event for purposes of saving work etc.} \item{ \code{addHandlerIdle}:}{ handler is called every so often, and can be used to update a widget's content. This method has an extra argument \code{interval} specifying the interval in milliseconds with a default of 1000 or 1 second. } } Although not handlers, the \code{addPopupMenu} method adds a popup menu to a mouse click. The popup menu is specified using a list that is passed to \code{gmenu}. A refinement of this is the \code{add3rdMousePopupmenu} method which puts the popupmenu on the right mouse click. The method \code{removeHandler} is used to remove a handler from an object. If an ID is specified, just that handler is removed, otherwise all handlers will be. To temporarily disable a handler, use \code{blockHandler} then \code{unblockHandler}. } % \value{} % \author{} % \note{} \seealso{\code{\link{gWidgets-methods}}} \examples{ \dontrun{ ## a default handler, useful for when action is enough to ## specify desired results handler.default = function(h,...) do.call(h$action,list(svalue(h$obj))) group = ggroup(horizontal=FALSE, container=gwindow("Click button")) button = gbutton("Click me", container=group) addhandlerclicked(button, handler=handler.default, action="print") ## use two widgets, one to update the other group = ggroup(horizontal=FALSE, container=gwindow("two widgets")) button = gbutton("click me", container=group) label = glabel("Button has not been clicked", container=group) addhandlerclicked(button, handler = function(h,...) { svalue(h$obj) <-"click me again" svalue(h$action) <- "Button has been clicked" }, action = label) ## lazy evaluation is not used here obj = 4 gbutton("click",container=TRUE, handler=function(h,...) print(h$action), action=obj) obj = 2 ## now click button and value of 4 will be printed, not 2 ## Whereas, if one uses a gWidget we get the same as lazy ## loading obj = gedit("4") gbutton("click",container=TRUE, handler=function(h,...) print(svalue(h$action)), action=obj) svalue(obj) <- "2" ## Now click and "2" is printed. ## remove handler, block handler, unblockhandler (latter two may not be implemented) b <- gbutton("click", container=gwindow()) id <- addHandlerClicked(b, handler=function(h,...) print("ouch")) ## click --> "ouch" blockHandler(b, id) ## now click -- nothing unblockHandler(b, id) ## now click -- "ouch" removeHandler(b, id) ## all gone now } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gcommandline.Rd0000644000176000001440000000315712165555742015600 0ustar ripleyusers\name{gcommandline} \alias{gcommandline} \title{A command line interface} \description{ This constructs a simple command line interface for R } \usage{ gcommandline(command = "", assignto = NULL, useGUI = TRUE, useConsole = FALSE, prompt = getOption("prompt"), width = 500, height = 0.6 * width, container = NULL, ...,toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{command}{Initial command to evalues } \item{assignto}{Assigns output to this variable is non-NULL} \item{useGUI}{Is result also printed to GUI. Use FALSE to get text-only instance} \item{useConsole}{Is result also printed to console?} \item{prompt}{Prompt to use} \item{width}{Width of widget in pixels} \item{height}{Height of widget in pixels} \item{container}{Optional container to attach to} \item{\dots}{Ignored for now} \item{toolkit}{Which GUI toolkit to use} } \details{ Additional commands can be added programmatically with the \code{svalue<-} method. The The value assigned is a string containing the command. If it has a \code{names} attribute, this is taken as the variable name to assign the output to. The \code{svalue} method returns the command history. The \code{"["} method can be used to retrieve the command history as well. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ obj = gcommandline(container=TRUE) svalue(obj) <- "2+2" ## assign to x command = "rnorm(100)"; names(command) = "x" svalue(obj) <- command ## look at history obj[] } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/glabel.Rd0000644000176000001440000000465611626236276014375 0ustar ripleyusers\name{glabel} \alias{glabel} \alias{svalue<-,gLabel-method} %%\alias{rotatelabel} \title{Constructors for label widget} \description{ This constructor produces a widget to display a line or multipline lines of text. For some toolkits, the text can be marked up. An option is available so that the displayed text can be edited. } \usage{ glabel(text = "", markup = FALSE, editable = FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{text}{Text to show in the label or button. For buttons, if this text matches a stock icon name, an icon is shown as well} \item{markup}{ Logical indicating if text for a label uses markup } \item{editable}{Logical. If TRUE, then the label's text can be set by clicking on the label and filling in the edit box. } \item{handler}{Handler called on a click event} \item{action}{ Passed to handler } \item{container}{Optional container to attach widget to.} % \item{obj}{a \code{glabel} instance} % \item{angle}{Angle to rotate label, in degrees} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue()} method returns the value of the widget. For a label, this is the text as a single string (which may not include a "\\n" for newlines if not supported by the toolkit). The \code{svalue<-()} method can be used to set the value of the widget. For labels and buttons, value with length greater than one are pasted together collapsed with "\\n". The \code{addhandlerclicked} method specifies a handler to be called on click events. Although in some toolkits, labels are meant to hold static text, gWidgets treats label widgets like other widgets allowing the user to bind handlers to mouse clicks. For labels, if \code{editable=TRUE} is specified, clicking on the text allows one to edit the label's value overriding the click handler in the process. However, the \code{addhandlerchanged} handler can be given to respond to the text after it has been chnaged. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ glabel("a label", container=TRUE) glabel("Click me to edit label", editable=TRUE, container=TRUE) glabel("Click me for a message", container=TRUE, handler=function(h,...) {cat("Hi\n")}) } } \keyword{ interface }% at least one, from doc/KEYWORDS gWidgets/man/ggraphics.Rd0000644000176000001440000000677612165556010015111 0ustar ripleyusers\name{ggraphics} \alias{ggraphics} \alias{ggraphicsnotebook} \title{Constructor for a toolkit specific plot device and a notebook to wrap plots in} \description{ If a toolkit provides a graphics device, such as the cairoDevice package does for GTK+ or qtutils for Qt, this constructor makes devices that can then be embedded in other widgets. The notebook interface is one such example. } \usage{ ggraphics(width = dpi * 6, height = dpi * 6, dpi = 75, ps = 12, container = NULL, ..., toolkit = guiToolkit()) ggraphicsnotebook(width=dpi*6, height=dpi*6,dpi=75, container = NULL,..., toolkit = guiToolkit()) } \arguments{ \item{width}{width in pixels of device} \item{height}{height in pixels of device} \item{dpi}{scale factor for default width and height} \item{ps}{pointsize} \item{container}{Optional container to attach widget to} \item{\dots}{ Passed to add method of container. } \item{toolkit}{Which GUI toolkit to use} } \details{ When multiple graphics devices are present, clicking in the window of one will make that the current device. The \code{visible<-} method makes the object the current device. The \code{svalue(obj, ..., value)} method will save the visible window to the file in \code{value}. In gWidgetsRGtk2, if the window has another window clipping part of it, this clipping will be shown. This "hack" is needed, as \code{dev.copy} does not currently work for the "cairo" graphic device. (In future versions, there will be support for pdf files within cairo.) The \code{addhandlerclicked(obj, handler, action, ...)} method where handler has first argument \code{h} has the additional values \code{h\$x} and \code{h\$y} where these are values are returned using "usr" coordinates (see \code{help("par")}). (This was in NDC coordinates) For \pkg{gWidgetsRGtk2} and \pkg{gWidgetsQt} there is also rubber-band selection implemented. The \code{addHandlerChanged} method can be used to call a handler when the selection is completed. The \code{x} and \code{y} components of \code{h} record the lower left and upper right points of the rectange. See the example for how this can do something similar to "brushing". } % \value{} % \author{} % \note{} \examples{ \dontrun{ win <- gwindow("Graphics example") ggraphics(ps=6, container=win) hist(rnorm(100)) ## This is for gWidgetsRGtk2 (along with cairoDevice) or qtutils library(gWidgets) options(guiToolkit="RGtk2") ## "Qt" w <- gwindow("brush example", visible=FALSE) g <- ggroup(container=w) tbl <- gtable(mtcars, container=g, filter.FUN="manual") size(tbl) <- c(300, 500) gg <- ggraphics(container=g) visible(w) <- TRUE makePlot <- function(ind) { plot(mpg ~ wt, mtcars) if(!missing(ind) && any(ind)) points(mpg ~ wt, mtcars[ind,], cex=2, pch=16, col="red") } ID <- addHandlerChanged(gg, handler=function(h,...) { x <- h$x; y <- h$y ind <- (mtcars$wt >= x[1]) & (mtcars$wt <= x[2]) & (mtcars$mpg >= y[1]) & (mtcars$mpg <= y[2]) ## udpate graphic and data frame makePlot(ind) if(any(ind)) visible(tbl) <- ind }) ## Example using a notebook. The device is raised on tab change library(gWidgets) options(guiToolkit="RGtk2") w <- gwindow("notebook example") nb <- gnotebook(container=w) devs <- lapply(1:5, function(i) ggraphics(container=nb, label=as.character(i))) addHandlerChanged(nb, handler=function(h,...) { ## Tricky part is svalue(h$obj) is not the new page number -- but old ## so we use the pageno component here gg <- h$obj[h$pageno] visible(gg) <- TRUE }) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-dnd.Rd0000644000176000001440000000715312034653511015447 0ustar ripleyusers\name{gWidgets-dnd} \alias{gWidgets-dnd} \alias{adddroptarget} \alias{adddropmotion} \alias{adddropsource} \alias{addDropTarget} \alias{addDropMotion} \alias{addDropSource} \title{Functions to add drag and drop ability to widgets} \description{ These functions allow drag and drop between widgets. The basic idea is that one creates drop sources from which one defines values which may be dragged and drop target where values may be dropped. These values can be text, or widgets. } \usage{ adddropsource (obj, targetType = "text", handler = NULL, action = NULL, ...) adddropmotion (obj, handler = NULL, action = NULL, ...) adddroptarget (obj, targetType = "text", handler = NULL, action = NULL, ...) } \arguments{ \item{obj}{Object to put drop handler on} \item{targetType}{What type of drop target: either "text" or "pixmap" or "entry".} \item{handler}{Handler called for the drop motion} \item{action}{action passed to handler} \item{...}{Not documented, currently has no role.} } \details{ To specify if one can drag values from a widget use \code{adddropsource} called on the object. The argument \code{targetType} can be set to \code{"object"} when the drop value is to be a widget, and not a string. The arguments \code{handler} and \code{action} can be used to describe what gets dropped. The default is to drop the widget's contents as returned by \code{svalue}. To specify if an object is a drop target the \code{adddroptarget} method is called on the object. The argument \code{handler} (but no \code{action}) is used to handle the drop. The handler's first argument is a list with named components. The \code{obj} component refers to the object that has the target placed on it. The component \code{dropdata} is set by the \code{adddropsource} method. The dropdata is typically a string, but a mechanism is in place to drop widgets. The default handler for \code{adddroptarget} is to replace the widget's value with the dropped data. To add an action to a motion event, use the \code{adddropmotion} method. The \code{adddroptarget} must first have been added to the object. } \value{ These functions return an ID returned when registering a handler. The function \code{removehandler} uses this information to remove a drag and drop handler. } \author{Implementation of Simon Urbanek's iwidgets API was done by Michael Lawrence and John Verzani } \seealso{\link{gWidgets-methods}} \examples{ \dontrun{ ## simple dnd lab = glabel("drag me",container=gwindow()) ed = gedit("drop here",container = gwindow()) adddropsource(lab) adddroptarget(ed) adddropmotion(ed,handler=function(h,...) print("bombs away")) ## more complicated ## this shows that rows of editable data frame can be dropped. ## by assigning to the changed signal, the graphs can be dynamic. ## THat is, drop a column, then edit it. The graph will update. The key ## is referring to the "value" stored in gd. This refers to the column ## in the editable data frame. ## By using svalue() and id(), the dropped value can also be a ## character string referring to a variable in the workspace. adf = gdf(mtcars, container = gwindow()) gd = ggraphics(container = gwindow()) plotData = function() { dropvalue = tag(gd,"value") theValues = svalue(dropvalue) theName = id(dropvalue) hist(theValues, xlab=theName, main="") } ids = adddroptarget(gd,targetType="object", handler = function(h,...) { tag(gd, "value") <- h$dropdata plotData() if(is.gdataframecolumn(h$dropdata)) { view.col = h$dropdata id = addhandlerchanged(view.col, handler=function(h,...) plotData()) } }) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-dialogs.Rd0000644000176000001440000001133612165555724016336 0ustar ripleyusers\name{gWidgets-dialogs} \alias{gWidgets-dialogs} \alias{gmessage} \alias{galert} \alias{gconfirm} \alias{ginput} \alias{gbasicdialog} \title{Basic dialog constructors} \description{ A dialog is a widget that draws its own window. These dialogs are used for simple things -- confirming a choice, gathering a single line of input, etc. Dialogs are always modal, meaning they must be closed before R can be interacted with again. } \usage{ gmessage(message, title="message", icon = c("info", "warning", "error", "question"), parent = NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) ginput(message, text="", title="Input", icon = c("info", "warning", "error", "question"), parent=NULL, handler = NULL, action = NULL,..., toolkit=guiToolkit()) gconfirm(message, title="Confirm", icon = c("info", "warning", "error", "question"), parent=NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) gbasicdialog(title = "Dialog", widget, parent=NULL, do.buttons=TRUE, handler = NULL, action=NULL, ..., toolkit=guiToolkit()) galert(message, title = "message", delay=3, parent=NULL, ..., toolkit=guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{message}{Message shown for widget} \item{title}{Title of window} \item{icon}{Which icon to show} \item{text}{default value for ginput text} \item{widget}{Widget to place in basic dialog. If missing, dialog returns a container.} \item{parent}{A gwindow() instance. If specified, dialog will be located in relation to this} \item{do.buttons}{For \code{gbasicdialog} -- when no \code{widget} argument is passed in -- this can be used to suppress the addition of Ok and Cancel buttons. If suppressed, the dialog can be closed by the window manager or programattically through the \code{dispose} method.} \item{handler}{Handler called on OK selection.} \item{action}{Value passed to handler} \item{delay}{For galert, how long the transient message will appear} \item{\dots}{Ignored} \item{toolkit}{Toolkit to use for GUI} } \details{ These basic dialogs do slightly different things. The \code{gmessage} dialog shows a message with an icon and a dismiss button. This dialog returns \code{TRUE} or \code{FALSE} as appropriate. The \code{gconfirm} dialog shows a message with an icon and an OK button and a dismiss button. A handler may be attached to the OK button selection. This dialog returns \code{TRUE} or \code{FALSE} as appropriate. The \code{ginput} dialog adds an edit box for gathering user information. The \code{text} argument sets the default value. This is then passed to the handler via the component \code{input} of the first argument of the handler. This dialog returns the value of the string if OK is clicked, otherwise \code{NA}. The \code{gbasicdialog} widget wraps a dialog (with buttons) around a widget. For \pkg{gWidgetsRGtk2} and \pkg{gWidgetsQt} the widget may be specified throuh the \code{widget} argument of the constructor. The constructor produces a modal dialog, hence no methods are defined. The return value is a logical indicating which button was clicked. More portably (hence encouraged), if the \code{widget} argument is NULL, then the constructor produces a container. This container becomes modal after a call to \code{visible(..., set=TRUE)} (not the assignment version though). Again the return value is a logical. This too creates a modal dialog. The handler specified to the constructor is called when OK is clicked and \code{TRUE} is returned. The value of \code{FALSE} is returned on cancel, and \code{NA} otherwise. The buttons may be suppressed by setting the argument \code{do.buttons=FALSE}. The dialog then may be closed by calling the \code{dispose} method within a callback. These dialogs are modal. This means that the R session freezes until the dialog is dismissed. This may be confusing to users if the window should appear below a currently drawn window. The \code{galert} dialog is non-modal and does not grab the focus. Like \code{gmessage} it shows a message but unlike it, only for a short period of time and is unobtrusive. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ gmessage("Hi there") gconfirm("Are we having fun?", handler = function(h,...) print("Yes")) ginput("Enter your name", icon="question", handler = function(h,...) cat("Hi",h$input,"\n")) ## gbasicdialog w <- gbasicdialog(title="Select a state", handler = function(h,...) print(svalue(tbl))) tbl <- gtable(data.frame(states = rownames(state.x77)), expand=TRUE, container = w) visible(w, set=TRUE) ## show dialog } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gedit.Rd0000644000176000001440000000433112165555754014235 0ustar ripleyusers\name{gedit} \alias{gedit} \title{Constructor for widget to handle single-line text input} \description{ The \code{gedit} widget is used to enter single lines of text. } \usage{ gedit(text = "", width = 25, coerce.with = NULL, initial.msg="", handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{text}{Initial text in widget} \item{width}{Width of widget. For gedit, this means the number of characters.} \item{coerce.with}{For gedit, when the value is retrieved this function is applied to the result. (The stored value is always a character, this can be used to make it numerc, to quote it, ...} \item{initial.msg}{If \code{text} is empty, this initial message is displayed to give the user some indication of what to do} \item{handler}{Handler called when text is changed. For gedit, this means the enter key is pressed.} \item{action}{ Passed to handler} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to add method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{gedit} widget has the following methods: The \code{svalue} method retrieves the value. If a function is given to the argument \code{coerce.with} it is applied before the value is returned. This can be used to coerce the text value (always of class character) to a numeric, or to a date, or to be quoted, ... The \code{svalue<-} method is used to set the value. The \code{"["} and \code{"[<-"} methods refer to the widgets "type-ahead" values. A familiar usage is when a url is typed into a web browser, matches appear from a users history that could possibly complete the typed url. The \code{visible<-} method is used to toggle whether characters are visible, or are replaced with a "*", such as is done with password entry. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ gedit("type here", container=gwindow()) ## change handler obj <- gedit(container=gwindow()) addhandlerchanged(obj, handler=function(h,...) cat("You typed", svalue(h$obj),"\n")) ## coerce to numeric obj <- gedit("7", container=gwindow(), coerce.with=as.numeric) svalue(obj) } } \keyword{interface } gWidgets/man/gformlayout.Rd0000644000176000001440000001745512034653547015516 0ustar ripleyusers\name{gformlayout} \alias{gformlayout} \title{A constructor for laying out groups of widgets from a template defined by a list} \description{ This constructor takes a list that defines the layout of widgets and pieces them together to create a form or dialog. It is similar to \code{ggenericwidget} but offers more flexibility with the layout, but does not offer the automatic creation of the widget using a functions \code{formals}. } \usage{ gformlayout(lst, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{lst}{A list that defines the layout of the containers. See the details section.} \item{container}{Optional parent container for the widget} \item{\dots}{Passed to \code{add} method of parent container when given} \item{toolkit}{Which GUI toolkit to use} } \details{ The list defining the layout has the following key named components: \describe{ \item{type}{The type is the name of a gWidgets constructor or "fieldset". The latter specifies that the children should be layed out using a table. The type can specify either a container constructor or component contstructor} \item{children}{For containers, this specifies the children using a list. Each child is a given as a component of this list. Children can be containers and hence contain other children, to match the heirarchical layout common in GUIs.} \item{name}{If a name is specified, then this widget will be stored in a list that can be accessed by the methods \code{svalue} or \code{\[}} \item{depends.on}{The name of a widget previously specified through the \code{name} argument. If given, then a handler is added to the widget that controls whether this new widget/container should be enabled.} \item{depends.FUN}{When \code{depends.on} is specified, this function is consulted to see if the widget should be enabled. This function has argument \code{value} which is the return value of \code{svalue} on the named widget this new one depends on. It should return a logical value indicating if the new widget is to be enabled.} \item{depends.signal}{By default, the signal the handler specified through \code{depends.FUN} is given by \code{addHandlerChanged}, this allows on to specify a different \code{addHandler} method. See the example.} } If the type is \code{gnotebook}, then each child should have a \code{label} component. The new constructor \code{fieldset} allows the organization of its children in a table. These children should not be other containers. If the component \code{label} is non-null, the table is packed into a \code{gframe} container. The default number of columns is just 1, but specifying \code{columns} in the list can increase this. Children are packed in row by row when more than one column is given. The labels can be adjusted. The component \code{label.pos} can be "left" (the default) for a label to the left of the widget, or "top" to have the label on top of the widget. When the position if "left", then the \code{label.just} component is consulted for justification of the label. This can have a value of "right" (the default), "center" or "left" If a component \code{label.font} is given, then this will be applied to each label through the \code{font} method of the label. The children are specified as a list. Each child should have a \code{type} component, a \code{label} component and a \code{name} component. Other components are passed to the specified constructor in type through \code{do.call}. The return object has a few methods defined for it. The \code{\[} method returns a list with named components storing the objects created by the constructors. Subsetting is allowed. No \code{\[\[} method is given, instead the \code{drop=TRUE} argument can be used with a single index is given to return the component and not the list containing the component. The \code{svalue} method is a convenience method that applies the \code{svalue} method to each component of the list returned by \code{\[}. The \code{names} method is a convenience method that gives the names of the widgets store in the list returned by \code{\[}. } % \value{} % \references{} % \author{} \note{The design of this borrows from the FormPanel and FormLayout constructors in the \url{extjs.com} library for javascript programming.} \seealso{\code{\link{ggenericwidget}}} \examples{ \dontrun{ ## layout a collection of widgets to generate a t.test tTest <- list(type = "ggroup", horizontal = FALSE, children = list( list(type="fieldset", columns = 2, label = "Variable(s)", label.pos = "top", label.font = c(weight="bold"), children = list( list(name = "x", label = "x", type = "gedit", text = ""), list(name = "y", label = "y", type = "gedit", text = "", depends.on = "x", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur" ) ) ), list(type = "fieldset", label = "Hypotheses", columns = 2, children = list( list(name = "mu", type = "gedit", label = "Ho: mu=", text = "0", coerce.with = as.numeric), list(name = "alternative", type="gcombobox", label = "HA: ", items = c("two.sided","less","greater") ) ) ), list(type = "fieldset", label = "two sample test", columns = 2, depends.on = "y", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur", children = list( list(name = "paired", label = "paired samples", type = "gcombobox", items = c(FALSE, TRUE) ), list(name = "var.equal", label = "assume equal var", type = "gcombobox", items = c(FALSE, TRUE) ) ) ), list(type = "fieldset", columns = 1, children = list( list(name = "conf.level", label = "confidence level", type = "gedit", text = "0.95", coerce.with = as.numeric) ) ) ) ) w <- gwindow("t.test") g <- ggroup(horizontal = FALSE, container = w) fl <- gformlayout(tTest, container = g, expand=TRUE) bg <- ggroup(container = g) addSpring(bg) b <- gbutton("run t.test", container = bg) addHandlerChanged(b, function(h,...) { out <- svalue(fl) out$x <- svalue(out$x) # turn text string into numbers via get() if(out$y == "") { out$y <- out$paired <- NULL } else { out$y <- svalue(out$y) } print(do.call("t.test",out)) }) } } \keyword{interface} gWidgets/man/gpanedgroup.Rd0000644000176000001440000000260412165556240015444 0ustar ripleyusers\name{gpanedgroup} \alias{gpanedgroup} \title{ A paned group holds two child components with a handle, or sash, between them to adjust the amount of space allocated to each } \description{ A constructor for a paned group. } \usage{ gpanedgroup(widget1=NULL, widget2=NULL, horizontal = TRUE, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{widget1}{Left (top) widget. Can be added at time of construction, or the \code{add} method can be used to add the child widgets one at a time.} \item{widget2}{Right (bottom) widget} \item{horizontal}{Left/right (\code{TRUE}) or top/bottom} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{add} method can be used to one child at a time. The \code{svalue} method returns the sash position with a value between 0 and 1. The \code{svalue<-} method can be used to specify the sash position with a value between 0 and 1. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ w <- gwindow("gpanedgroup example") pg <- gpanedgroup(container=w) gvarbrowser(container = pg) ## first is left/top gtext(container = pg) svalue(pg) <- 0.25 } } \keyword{interface }% at least one, from doc/KEYWORDS gWidgets/man/gsvg.Rd0000644000176000001440000000260511406427005014071 0ustar ripleyusers\name{gsvg} \alias{gsvg} \title{Constructor for widget to show SVG files} \description{ Some toolkit packages provide a widget to display an SVG file. This widget allows this to be embedded within a gWidgets window. } \usage{ gsvg( filename="", width=480, height=480, handler=NULL, action=NULL, container = NULL, ... , toolkit=guiToolkit()) } \arguments{ \item{filename}{SVG file} \item{width}{width in pixels of widget} \item{height}{height in pixels of widget} \item{handler}{Called on click event} \item{action}{Used to parameterize callback specified by handler} \item{container}{Container to attach widget to} \item{\dots}{ Passed to add method of container. } \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue} method returns the current filename. The \code{svalue<-} method can be used to set a new file to display. The \code{addhandlerclicked(obj, handler, action, ...)} method where handler has first argument \code{h} has the additional values \code{h\$x} and \code{h\$y} where these are pixel values for where the mouse click occurred. } % \value{} % \author{} \note{This is implemented in Qt only (and gWidgetsWWW).} \examples{ \dontrun{ f = tempfile() svg(f) hist(rnorm(100)) dev.off() win <- gwindow("Graphics example") gsvg(f, container=win) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gnotebook.Rd0000644000176000001440000000675212165556162015133 0ustar ripleyusers\name{gnotebook} \alias{gnotebook} %- Also NEED an '\alias' for EACH other topic documented here. \title{constructor for notebook widget} \description{ A notebook widget organizes different pages using tabs, allowing only one page to be shown at once. Clicking on the tab raises the associated page. } \usage{ gnotebook(tab.pos = 3, closebuttons = FALSE, dontCloseThese = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{tab.pos}{Where to place tabs (1 bottom, 2 left side, 3 top, 4 right side} \item{closebuttons}{Is there a close button in the tab?} \item{dontCloseThese}{If \code{closebuttons=TRUE} this will make it impossible to remove these tabs. Specified by tab number} \item{container}{Optional parent container to attach notebook widget to } \item{\dots}{passed to \code{add} method of parent container} \item{toolkit}{Which GUI toolkit to use} } \details{ In what follows, it is useful to think of a notebook as a vector with named entries, each entry being a widget, the name being the tab label. Notebooks have the following methods: New pages are added with the \code{add} method, which most likely is called by the widget constructor. The extra argument \code{label} is used to specify the tab label. This may be a string, or in gWidgetsRGtk2 a \code{glabel} instance. The extra argument \code{index} can be used to specify which page to add to. By default, a new page is created at the end of the notebook. In gWidgetsRGtk2, the extra argument \code{override.closebutton} can be used to add or not add a close button in the tab label. The \code{svalue} method returns the current page number. The \code{svalue<-} method is used to set the page number. The \code{dispose} method will remove the currently selected page unless it is overridden by the value of \code{dontCloseThese}. The \code{delete(obj, widget,...)} method will delete the widget on a given page. For some toolkits, the unparented widget can be reparented with the \code{add} method or \code{[<-}. The \code{length} method returns the number of pages. The \code{names} method returns the tab labels. The \code{names<-} method may be used to replace the tab labels. Something like \code{names(obj)[1]<-"new label"} should work. The \code{"["} method refers to the widgets in the notebook. It returns a single widget or list of widgets. For some toolkits, the \code{"[<-"} method may be used to replace a widget on a notebook page. The \code{addHandlerChanged} method passes the component \code{pageno} when the page index returned by \code{svalue} within the handler refers to the tab before it was changed. The following could be used to get the right one in a portable way: \code{if(is.null(h$pageno)) svalue(h$obj) else h$pageno} } % \value{} % \references{} % \author{} % \note{} \seealso{See \code{\link{gwindow}} for top-level containers, \code{\link{ggroup}}, \code{\link{gframe}} and \code{\link{gexpandgroup}} for box containers} \examples{ \dontrun{ w <- gwindow("gnotebook example") nb <- gnotebook(container=w) ## "add" called by constructor glabel("Widget 1", container=nb, label="page 1") ## label argument passed by constructor to add method glabel("Widget 2", container=nb, label="page 2") length(nb) names(nb) names(nb)[1] <- "Page 1" svalue(nb) <- 2 dispose(nb) ## dispose current tab length(nb) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gfile.Rd0000644000176000001440000000640412165555772014232 0ustar ripleyusers\name{gfile} \alias{gfile} \alias{gfilebrowse} \alias{gcalendar} \title{Dialogs for file and date selection} \description{ These functions provide dialogs for file selection (files or directories) and date selections. } \usage{ gfile(text = "", type = c("open", "save", "selectdir"), initialfilename = NULL, filter = list("All files" = list(patterns = c("*")), "R files" = list(patterns = c("*.R","*.Rdata")), "text files" = list(mime.types = c("text/plain")) ), multi=FALSE, handler = NULL, action = NULL, ..., toolkit = guiToolkit()) gfilebrowse (text = "Select a file...", type = "open", quote = TRUE, container = NULL, ..., toolkit = guiToolkit()) gcalendar(text = "", format = "\%Y-\%m-\%d", handler=NULL, action=NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{text}{Initial text. For thecalendar, an optional date in a form matching \code{format}} \item{type}{When selecting a file it can be selected for opening, for saving or you may want to select a directory.} \item{initialfilename}{Suggested name for file save} \item{filter}{Filter for files shown during selection. Can be nested list, as in example or a named character vector with the names a description and value a file extension (no dots) of files endings to match. } \item{multi}{Logical. Allow selection of multiple files?} \item{quote}{Is result quoted} \item{format}{Format of date, default is year-month-day} \item{handler}{Handler for when file is changed. The component \code{file} of the first argument contains the file name} \item{action}{ Passed to handler } \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{gedit} instance} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{gfile} dialog is modal, meaning no action can take place until a selection is made. Whereas the \code{gfilebrowse} dialog consists of a \code{gedit} instance to hold a filename and a button to click if the dialog is desired to fill in this filename. The \code{gcalendar} widget is similar to the \code{gfilebrowse} widget. For both \code{gcalendar} and \code{gfilebrowse} any \code{...} arguments are passed to \code{gedit}. The \code{coerce.with} argument can be used to here to quote the values, or coerce them otherwise such as with \code{as.Date}. Otherwise, the \code{svalue} method returns a character string containing the value shown in the \code{gedit} box. The \code{svalue<-()} method may be used to set the value for both \code{gcalendar} and \code{gfilebrowse} . The return value is the filename selected. A \code{NA} value is returned if no file is selected. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## source a file using a handler sourceFile <- function() gfile("Select a file",type="open", handler = function(h,...) source(h$file)) ## source an R file using fact that dialog is modal source(gfile(filter=c("R files"="R"))) ## apply a generic action to the file countLines <- function(filename) print(length(readLines(filename))) chooseFile <- function() gfile("Select a file",type="open", action="countLines", handler = function(h,...) do.call(h$action,list(h$file))) } } \keyword{interface} gWidgets/man/gWidgets-classes.Rd0000644000176000001440000000441111462702035016331 0ustar ripleyusers\name{gWidgets-classes} \alias{gWidgets-classes} \alias{gAction-class} \alias{gButton-class} \alias{gCalendar-class} \alias{gCheckbox-class} \alias{gCheckboxGroup-class} \alias{gCombobox-class} \alias{gCommandline-class} \alias{gDf-class} \alias{gDfNotebook-class} \alias{gEdit-class} \alias{gExpandGroup-class} \alias{gFilebrowse-class} \alias{gFormLayout-class} \alias{gFrame-class} \alias{gGenericWidget-class} \alias{gGraphics-class} \alias{gGraphicsNotebook-class} \alias{gGridComponent-class} \alias{gGroup-class} \alias{gHelp-class} \alias{gHelpBrowser-class} \alias{gHtml-class} \alias{gImage-class} \alias{gLabel-class} \alias{gLayout-class} \alias{gMenu-class} \alias{gNotebook-class} \alias{gPanedGroup-class} \alias{gRadio-class} \alias{gSeparator-class} \alias{gSlider-class} \alias{gSpinbutton-class} \alias{gStatusbar-class} \alias{gSvg-class} \alias{gTable-class} \alias{gText-class} \alias{gToolbar-class} \alias{gTree-class} \alias{guiComponentRangeSelector-class} \alias{guiComponentWithItems-class} \alias{gVarBrowser-class} \alias{gWindow-class} \alias{gCommandlineANY-class} \alias{gGenericWidgetANY-class} \alias{gFormLayoutANY-class} \alias{gHelpbrowserANY-class} \alias{gHelpANY-class} \title{Classes for gWidgets instances} \description{ Classes for gWidgets objects } \details{ The gWidgets API is designed to have a double dispatch. The gWidgets package calling methods in the gWidgetsXXX packages. As such, the real class structure sits inside the toolkit packages. These classes are merely here for organization and some day documentation. The "ANY" classes are a means to write compound widgets in gWidgets that work across the toolkits. gAction gButton gCalendar gCheckbox gCheckboxGroup gCombobox gCommandline gDf gDfNotebook gEdit gExpandGroup gFilebrowse gFormLayout gFrame gGenericWidget gGraphics gGraphicsNotebook gGroup gHelp gHelpBrowser gHtml gImage gLabel gLayout gMenu gNotebook gPanedGroup gRadio gSeparator gSlider gSpinbutton gStatusbar gSvg gTable gText gToolbar gTree guiComponentRangeSelector guiComponentWithItems gVarBrowser gWindow gCommandlineANY gGenericWidgetANY gFormLayoutANY gHelpbrowserANY gHelpANY } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gimage.Rd0000644000176000001440000000502712165556216014367 0ustar ripleyusers\name{gimage} \alias{gimage} \title{Constructor to show images} \description{ This constructor produces a widget intended to show images stored as files on the file system. } \usage{ gimage(filename = "", dirname = "", size = "", handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{filename}{Specifies location of image. May be a stock icon name or filename. (In the future may be a url.)} \item{dirname}{Directory of file. If "stock", then a stock icon is used.} \item{size}{Size of image when stock image is used. Values are in \code{c("menu", "small_toolbar","large_toolbar","button","dialog")}} \item{handler}{Handler called on a click event} \item{action}{ Passed to handler } \item{container}{Optional container to attach widget to.} % \item{obj}{a \code{glabel} instance} % \item{angle}{Angle to rotate label, in degrees} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue()} method returns the filename of the figure or the stock icon name, if the icon was set from a stock icon. The \code{svalue<-()} method can be used to set the value of the widget. The value is a filename containing the image to display. The \code{addhandlerclicked} method is called on click events. } % \value{} % \references{} % \author{} % \note{} \seealso{See \code{\link{getStockIcons}} to get a list of available icons and \code{\link{addStockIcons}} to add to this list.} \examples{ \dontrun{ w <- gwindow("Stock icon example") gimage("ok",dirname="stock", container = w) ## example contributed by Richard Cotton w <- gwindow("Help button window") add_help_button <- function(help_text, container = w, width = getOption("width"), indent = 2, ...) { gimage("help", dirname = "stock", container = container, handler = function(h, ...) { help_win <- gwindow("Help") help_label <- glabel(text= strwrap(help_text, width = width, indent = indent), container = help_win) }) } add_help_button(paste("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "Nunc magna magna, vestibulum sit amet posuere sit amet, ", "gravida placerat odio.", "Integer et purus lorem, quis suscipit risus.", collapse=" ")) } } \keyword{ interface }% at least one, from doc/KEYWORDS gWidgets/man/gcheckbox.Rd0000644000176000001440000000367511626236527015103 0ustar ripleyusers\name{gcheckbox} \alias{gcheckbox} \alias{[<-,gCheckbox-method} \title{ Constructor of widget to indicate whether a value is desired or not } \description{ A checkbox shows a value and a box to check indicating if the value is desired or not. } \usage{ gcheckbox(text, checked = FALSE, use.togglebutton=FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{text}{Text to show by box} \item{checked}{Logical indicating initial state of box} \item{use.togglebutton}{Logical indicating if a toggle button should be used (depresses when \code{TRUE}) in place of a check box} \item{handler}{ Called when box is toggled.} \item{action}{ Passed to handler} \item{container}{ Optional container to attach widget to.} \item{...}{Not documented, currently has no role.} \item{toolkit}{Which toolkit to use?} } \details{ The value of the widget is either \code{TRUE} or \code{FALSE}. The \code{svalue} method returns a logical indicating \code{TRUE} if the box is checked. The \code{svalue<-} method can be used to set the value using a logical. The \code{"["} method returns the label on the box. The \code{"[<-"} method can be used to change the label on the box. The default handler is set by the \code{addHandlerClicked} method. This is called when the button is toggled. If one wishes to have the handler called only when checked to indicate \code{TRUE}, say, one should check the state of the widget in the handler (e.g., \code{if(svalue(h$obj))}). } %%\value{} %%\references{} \author{John Verzani} %%\note{} \seealso{ Methods for gComponent objects are detailed in \code{\link{gWidgets-methods}}. Event Handlers are detailed in \code{\link{gWidgets-handlers}}. } \examples{ \dontrun{ gcheckbox("checked", container=TRUE, handler=function(h,...) { cat("The widget is checked?",svalue(h$obj), "\n") }) } } \keyword{ interface } gWidgets/man/glayout.Rd0000644000176000001440000000545611612430274014617 0ustar ripleyusers\name{glayout} \alias{glayout} %- Also NEED an '\alias' for EACH other topic documented here. \title{A container for aligning widgets in a table} \description{ A container for laying out widgets in a table. The widgets are added using matrix notation (\code{[i,j]<-}). } \usage{ glayout(homogeneous = FALSE, spacing = 10, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{homogeneous}{A logical indicating if the cells are all the same size} \item{spacing}{Spacing in pixels between cells} \item{container}{Optional container to attach widget to.} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ Widgets are added using matrix notation. A widget can span several cells, for instance \code{obj[1:2,2:3] <- widget} would place the widget in the first and second rows and second and third columns. The matrix notation is to specify the space allocated to the widget. For \code{gWidgetstcltk}, it is necessary for a child widget to have the layout object as its parent container and to call the \code{[<-} method to add the widget. (See the example.) As a convenience, if the value to be assigned is a character it will be turned into a \code{glabel} object before being added. Like \code{ggroup}, the extra argument \code{expand} can be used to force the widget to expand to fill all the space allocated to it. Like \code{ggroup}, the extra argument \code{anchor} can by used to anchor the child within the space allocated when this space islarger than needed by the widget. This is specified as a pair of values from -1,0,1 to indicating the x and y positioning of the widget within the cell. Like \code{ggroup}, the extra argument \code{fill} can by used when \code{expand} is given, but not \code{anchor}, to have the widget expand in the \code{x} direction, the \code{y} direction, or \code{both} (the default). (Toolkit specific). The method \code{[} can be used to subset. In the simplest usage, it returns the item at index i,j. (The item at i,j may be in other cells too. The return value is a gwidget if 1x1, a list if 1xn or mx1 (n>1), or a mxn matrix of items. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## show part of mtcars dataframe in a layout w <- gwindow("glayout example") tbl <- glayout(container = w) tbl[1,1] <- "a label" ## need container argument in gWidgetstcltk, gWidgetsRwxwidgets ## so we always use it. tbl[1,2, expand = TRUE] <- gedit("edit here", container=tbl) tbl[2,1, anchor = c(-1,-1)] <- glabel("ll", container = tbl) ## extraction: tbl[1,1] # glabel instance tbl[1,2] # gedit instance, ... } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/guiWidget-class.Rd0000644000176000001440000001324111547451761016170 0ustar ripleyusers\name{guiWidget-class} \docType{class} \alias{guiWidget-class} \alias{guiComponent-class} \alias{guiContainer-class} \alias{guiDialog-class} \alias{guiWidgetOrNULL-class} \alias{gWidgetANY-class} \alias{gComponentANY-class} \alias{gContainerANY-class} \title{Class "guiWidget" ~~~ } \description{Base class for gWidget objects} \section{Objects from the Class}{ Objects can be created by calls of the form \code{new("guiWidget", ...)}. These objects have two slots: a widget provided by a guiToolkit and a toolkit. Method dispatch is done on both values. } \section{Slots}{ \describe{ \item{\code{toolkit}:}{Object of class \code{"guiWidgetsToolkit"}. A specification of which GUI toolkit the widget uses.} \item{\code{widget}:}{Object of class \code{"ANY"}. A widget returned by the corresponding toolkit function. } } } \section{Methods}{ \describe{ \item{.add}{\code{signature(obj = "guiWidget", toolkit = "guiWidgetsToolkitRGtk2", value = "ANY")}: ... } \item{.add}{\code{signature(obj = "guiWidget", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidgetORgWidgetRGtkORRGtkObject")}: ... } \item{.add}{\code{signature(obj = "gContainerRGtk", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidget")}: ... } \item{.add}{\code{signature(obj = "gMenuRGtk", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidget")}: ... } \item{.add}{\code{signature(obj = "gNotebookRGtk", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidget")}: ... } \item{.add}{\code{signature(obj = "gTextRGtk", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidget")}: ... } \item{.delete}{\code{signature(obj = "gContainerRGtk", toolkit = "guiWidgetsToolkitRGtk2", widget = "guiWidget")}: ... } \item{.delete}{\code{signature(obj = "RGtkObject", toolkit = "guiWidgetsToolkitRGtk2", widget = "guiWidget")}: ... } \item{.delete}{\code{signature(obj = "gMenuRGtk", toolkit = "guiWidgetsToolkitRGtk2", widget = "guiWidget")}: ... } \item{.svalue<-}{\code{signature(obj = "gMenuRGtk", toolkit = "guiWidgetsToolkitRGtk2", value = "guiWidget")}: ... } \item{.tag}{\code{signature(obj = "guiWidget", toolkit = "guiWidgetsToolkitRGtk2")}: ... } \item{.tag<-}{\code{signature(obj = "guiWidget", toolkit = "guiWidgetsToolkitRGtk2")}: ... } \item{[}{\code{signature(x = "guiWidget")}: ... } \item{[<-}{\code{signature(x = "guiWidget")}: ... } \item{add3rdmousepopupmenu}{\code{signature(obj = "guiWidget")}: ... } \item{add}{\code{signature(obj = "guiWidget")}: ... } \item{addSpace}{\code{signature(obj = "guiWidget")}: ... } \item{addSpring}{\code{signature(obj = "guiWidget")}: ... } \item{adddropmotion}{\code{signature(obj = "guiWidget")}: ... } \item{adddropsource}{\code{signature(obj = "guiWidget")}: ... } \item{adddroptarget}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerchanged}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerclicked}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerdestroy}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerdoubleclick}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerexpose}{\code{signature(obj = "guiWidget")}: ... } \item{addhandleridle}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerkeystroke}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerrightclick}{\code{signature(obj = "guiWidget")}: ... } \item{addhandlerunrealize}{\code{signature(obj = "guiWidget")}: ... } \item{addpopupmenu}{\code{signature(obj = "guiWidget")}: ... } \item{defaultWidget}{\code{signature(obj = "guiWidget")}: ... } \item{defaultWidget<-}{\code{signature(obj = "guiWidget")}: ... } \item{delete}{\code{signature(obj = "guiWidget")}: ... } \item{dim}{\code{signature(x = "guiWidget")}: ... } \item{dimnames}{\code{signature(x = "guiWidget")}: ... } \item{dimnames<-}{\code{signature(x = "guiWidget")}: ... } \item{dispose}{\code{signature(obj = "guiWidget")}: ... } \item{editable}{\code{signature(obj = "guiWidget")}: ... } \item{editable<-}{\code{signature(obj = "guiWidget")}: ... } \item{enabled}{\code{signature(obj = "guiWidget")}: ... } \item{enabled<-}{\code{signature(obj = "guiWidget")}: ... } \item{focus}{\code{signature(obj = "guiWidget")}: ... } \item{focus<-}{\code{signature(obj = "guiWidget")}: ... } \item{tooltip<-}{\code{signature(obj = "guiWidget")}: ... } \item{font}{\code{signature(obj = "guiWidget")}: ... } \item{font<-}{\code{signature(obj = "guiWidget")}: ... } \item{id}{\code{signature(obj = "guiWidget")}: ... } \item{id<-}{\code{signature(obj = "guiWidget")}: ... } \item{length}{\code{signature(x = "guiWidget")}: ... } \item{names}{\code{signature(x = "guiWidget")}: ... } \item{names<-}{\code{signature(x = "guiWidget")}: ... } \item{removehandler}{\code{signature(obj = "guiWidget")}: ... } \item{size}{\code{signature(obj = "guiWidget")}: ... } \item{size<-}{\code{signature(obj = "guiWidget")}: ... } \item{svalue}{\code{signature(obj = "guiWidget")}: ... } \item{svalue<-}{\code{signature(obj = "guiWidget")}: ... } \item{tag}{\code{signature(obj = "guiWidget")}: ... } \item{tag<-}{\code{signature(obj = "guiWidget")}: ... } \item{update}{\code{signature(object = "guiWidget")}: ... } \item{visible}{\code{signature(obj = "guiWidget")}: ... } \item{visible<-}{\code{signature(obj = "guiWidget")}: ... } \item{isExtant}{\code{signature(obj = "guiWidget")}: ... } } } \author{John Verzani} \note{ Within gWidgets there are three main subclasses guiContainers, guiComponents and guiDialogs. The distinctions are more clear at the toolkit level. } % \seealso{} % \examples{} \keyword{classes} gWidgets/man/ggenericwidget.Rd0000644000176000001440000001265011406427005016113 0ustar ripleyusers\name{ggenericwidget} \alias{ggenericwidget} %%\alias{autogenerategeneric} %%\alias{geditlist} %%\alias{geditnamedlist} %%\alias{gvariables} \title{A constructor to create widgets for evaluating functions} \description{ This constructor creates a widget for collecting arguments for a function using a list to define the widget's components. When called with a function name a list is created on the fly which can be used as is, or modified as desired. } \usage{ ggenericwidget(lst, cli = NULL, container = NULL, ..., toolkit = guiToolkit()) } %% also could do: %autogenerategeneric(f, help = fName, variableType = NULL) %geditlist(...) %geditnamedlist(...) %gvariables(variableType = NULL, ...) \arguments{ \item{lst}{Either a list defining the widget or a function name as a string. In the latter case, the defining list may be retrieved by the \code{svalue} method.} %% \item{variableType}{Type of variable. One of %% \code{c("univariate","univariatetable", "bivariate", "model", %% "lattice")}} \code{x=} for initial variable name. \item{cli}{An instance of \code{gcommandline} or NULL. If NULL, then a new command line pops up in its own window} \item{container}{Optional container to attach widget to} %% \item{f}{Name of function} %% \item{help}{What man page should be used to look up arguments to function} \item{\dots}{Currently ignored by \code{ggenericwidget}, but passed along to \code{gedit} by \code{geditlist} and \code{geditnamedlist}} \item{toolkit}{Which GUI toolkit to use} } \details{ This widget provides an easy way to create dialogs that collect the arguments for a function evaluation. When the OK button is clicked, the arguments are collected and passed along to the function specified via the \code{action} part of the list. When collecting the arguments, empty strings are not passed along. The easiest usage is to simply provide a function name and have \code{autogenerategeneric} take a stab. However, in the long run it might be better to use \code{autogenerategeneric} to create an initial list, and then modify this to adjust the widget's look. The list contains several named components \describe{ \item{title}{The title for the widget} \item{help}{What help page is called} \item{type}{Either "text" or "graphic." Currently ignored.} \item{variableType}{Describes the type of variable. Either "univariate", "univariatetable","fileurl","bivariate", "model", "lattice", "lmer" or \code{NULL}. This value is passed directly to \code{gvariables}. For non-NULL values, the widget shows an appropriate area for collecting the main variable. For the model and lattice interfaces buttons allow editing of fields by subsequent dialogs. } \item{variableTypeExtras}{An optional list with components \code{name} and \code{value} containing a name and value passed along to the constructor for the variable type. Useful to override default } \item{assignto}{If TRUE, creates box for collecting name for assigning output} \item{action}{a list with named components \code{beginning} and \code{ending}. The arguments are collected and pasted together to form a string containing the R command to execute. These get put at the beginning and end of the string. A typical pair would be something like "prop.test(" and ")".} \item{arguments}{a list with named components. In the simplest usage the names are argument names, and the components are lists with entries that create the corresponding widget. The first such component is called \code{type} and is the name of a gWidget, such as \code{"gradio"}. Subsequent components are passed to this function using \code{do.call}. The constructors \code{geditlist} and \code{geditnamedlist} can be used when the input is to be a list of values or a list of named values. In the more complicated cases, these named components can be grouped into a list component. The name of this is then used to block the arguments. See the example. } } The \code{svalue} method returns the value of the list. This can be used to retrieve the list that is created when the constructor is called with a function name. } % \value{} % \references{} % \author{} \note{This function may be improved and the list defining it changed.} %\seealso{} \examples{ \dontrun{ ## a sample list definition ## Save some typing by defining a list to be used more than once later TRUE.list <- list( type = "gradio", items = c("TRUE","FALSE") ) ## define a list for producing a histogram widget hist.list <- list( title = "hist()", help = "hist", action = list( beginning = "hist(", ending = ")" ), type = "graphic", # either text or graphic variableType = "univariate", # single variable arguments = list( adjustments = list( breaks= list( type="gdroplist", items=c("\"Sturges\"","\"Scott\"","\"Friedman-Diaconis\"") ), probability = TRUE.list, include.lowest = TRUE.list, right = TRUE.list, shading = list( density = list( type="gedit", text=NULL ), angle = list( type="gedit", coerce.with="as.numeric", text="45" ) ) ) ) ) ggenericwidget(hist.list, container=TRUE) ## or to autogenerate one ggenericwidget("boxplot.default", container=TRUE) } } \keyword{interface} gWidgets/man/gwindow.Rd0000644000176000001440000000756112034653432014612 0ustar ripleyusers\name{gwindow} \alias{gwindow} %- Also NEED an '\alias' for EACH other topic documented here. \title{Constructor for base container} \description{ Widgets are packed inside containers which may in turn be packed inside other containers. The base container is known as a window. Only one container may be packed inside a window. } \usage{ gwindow(title = "Window", visible = TRUE, name=title, width = NULL, height= NULL, parent=NULL, handler = NULL, action = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{title}{Title of window} \item{visible}{If \code{TRUE} window is drawn when constructed. Otherwise, window can be drawn latter using \code{visible<-}. This value can default to \code{FALSE} by setting the option: \code{options("gWidgets:gwindow-default-visible-is-false"=TRUE)}. There are advantages: windows can draw slowly when adding item by item; \code{ggraphics} like to be added to an undrawn widget as this avoids a sizing issue.} \item{name}{Name for registry of windows} \item{width}{Default width for window at creation} \item{height}{Default height for window at creation} \item{parent}{If non-NULL, can be used to suggest default location of window. The argument name was changed from location to parent. This can be a coordinate pair (x,y) with (0,0) the upper left corner, or a gwindow instance. In the latter case the location is suggested by the location of the current window. This is useful for placing dialogs near the parent window.} \item{handler}{Handler for destroy event.} \item{action}{Passed to handler} \item{\dots}{Not used} \item{toolkit}{Which GUI toolkit to use} } \details{ A base window can also be created using the argument \code{container=TRUE} when constructing a widget. The \code{svalue} method returns the window title. Use \code{svalue<-} to change the title. The \code{add} method is used to add a widget or container to the base window. For top-level windows, some toolkits only support adding one widget, so in gWidgets only one widget should be added to a window, so usually it would be another container. Additionally the menubar, toolbar and statusbar widgets should now be added and deleted from the top-level window. Outside of RGtk2, the other toolkits expect these items to be properties of a top-level window. The \code{dispose} method destroys the window. The \code{size} method sets the minimum size. Use the \code{width} and \code{height} arguments to set the default size when the window is constructed. A window is destroyed in response to a destroy event. However, when the window managager tries to close a window first a "delete-event" is issued. If this has the right value then the "destroy" event is fired. The \code{addHandlerUnrealize} handler can be called to intercept the closing of the window. Its handler should return a logical: \code{TRUE} to prevent the closing, \code{FALSE} to proceed. This may not work on all toolkits } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ ## window with handler win <- gwindow("Window example", handler=function(h,...) { print("See ya") }) gbutton("cancel", container=win, handler = function(h,...) dispose(win)) ## block closing of window win <- gwindow("Window example") addHandlerUnrealize(win, handler = function(h,...) { val <- gconfirm("Really close window", parent=h$obj) if(as.logical(val)) return(FALSE) # destroy else return(TRUE) # don't destroy }) ## transient dialog (gWidgetsRGtk2) pwin <- gwindow("Parent window") cwin <- gwindow("Child window", parent = pwin) ## clicking button close parent causing child to close too gbutton("close both", container=cwin, handler = function(h,...) dispose(pwin)) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gWidgets-methods.Rd0000644000176000001440000004042711615331044016344 0ustar ripleyusers\name{gWidgets-methods} \alias{gWidgets-methods} \alias{.add,guiWidget,guiWidgetsToolkitRGtk2,ANY-method} \alias{.add,guiWidget,guiWidgetsToolkitRGtk2,guiWidgetORgWidgetRGtkORRGtkObject-method} \alias{.add,gContainerRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.add,gHelpANY,ANY,ANY-method} \alias{.add,gMenuRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.add,gNotebookRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.add,gTextRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.delete,gContainerRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.delete,RGtkObject,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.delete,gMenuRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.svalue<-,gMenuRGtk,guiWidgetsToolkitRGtk2,guiWidget-method} \alias{.tag,guiWidget,guiWidgetsToolkitRGtk2-method} \alias{.tag<-,guiWidget,guiWidgetsToolkitRGtk2-method} \alias{[,guiWidget-method} \alias{[,gLayout-method} \alias{[<-,guiWidget-method} \alias{add3rdmousepopupmenu,guiWidget-method} \alias{add,guiWidget-method} \alias{add,guiComponent-method} \alias{add,guiContainer-method} \alias{addSpace,guiWidget-method} \alias{addSpace,gGroup-method} \alias{addSpring,guiWidget-method} \alias{addSpring,gGroup-method} \alias{adddropmotion,guiWidget-method} \alias{adddropsource,guiWidget-method} \alias{adddroptarget,guiWidget-method} \alias{addhandler,guiWidget-method} \alias{addHandler,guiWidget-method} \alias{addhandlerchanged,guiWidget-method} \alias{addhandlerclicked,guiWidget-method} \alias{addhandlerdestroy,guiWidget-method} \alias{addhandlerdoubleclick,guiWidget-method} \alias{addhandlerexpose,guiWidget-method} \alias{addhandleridle,guiWidget-method} \alias{addhandlerkeystroke,guiWidget-method} \alias{addhandlerrightclick,guiWidget-method} \alias{addhandlerunrealize,guiWidget-method} \alias{addhandlermousemotion,guiWidget-method} \alias{addHandlerMouseMotion,guiWidget-method} \alias{addHandlerBlur,guiWidget-method} \alias{addhandlerblur,guiWidget-method} \alias{addHandlerFocus,guiWidget-method} \alias{addhandlerfocus,guiWidget-method} \alias{addHandlerColumnClicked,guiWidget-method} \alias{addhandlercolumnclicked,guiWidget-method} \alias{addHandlerColumnDoubleclick,guiWidget-method} \alias{addhandlercolumndoubleclick,guiWidget-method} \alias{addHandlerColumnRightclick,guiWidget-method} \alias{addhandlercolumnrightclick,guiWidget-method} \alias{addpopupmenu,guiWidget-method} \alias{add3rdMousePopupmenu,guiWidget-method} \alias{addDropMotion,guiWidget-method} \alias{addDropSource,guiWidget-method} \alias{addDropTarget,guiWidget-method} \alias{addHandlerChanged,guiWidget-method} \alias{addHandlerClicked,guiWidget-method} \alias{addHandlerDestroy,guiWidget-method} \alias{addHandlerDoubleclick,guiWidget-method} \alias{addHandlerExpose,guiWidget-method} \alias{addHandlerIdle,guiWidget-method} \alias{addHandlerKeystroke,guiWidget-method} \alias{addHandlerRightclick,guiWidget-method} \alias{addHandlerUnrealize,guiWidget-method} \alias{addPopupmenu,guiWidget-method} \alias{blockhandler,guiWidget-method} \alias{blockHandler,guiWidget-method} \alias{unblockhandler,guiWidget-method} \alias{unblockHandler,guiWidget-method} \alias{removeHandler,guiWidget-method} \alias{defaultWidget,guiWidget-method} \alias{defaultWidget,gButton-method} \alias{defaultWidget<-,guiWidget-method} \alias{defaultWidget<-,gButton-method} \alias{delete,guiWidget-method} \alias{delete,guiContainer-method} \alias{dim,guiWidget-method} \alias{dimnames,guiWidget-method} \alias{dimnames<-,guiWidget-method} \alias{dispose,guiWidget-method} \alias{editable,guiWidget-method} \alias{editable<-,guiWidget-method} \alias{enabled,guiWidget-method} \alias{enabled<-,guiWidget-method} \alias{focus,guiWidget-method} \alias{focus,guiComponent-method} \alias{focus<-,guiWidget-method} \alias{focus<-,guiComponent-method} \alias{font,guiWidget-method} \alias{font<-,guiWidget-method} \alias{id,guiWidget-method} \alias{id<-,guiWidget-method} \alias{insert} \alias{insert,guiComponent-method} \alias{insert,gText-method} \alias{length,guiWidget-method} \alias{names,guiWidget-method} \alias{names<-,guiWidget-method} \alias{removehandler,guiWidget-method} \alias{size,guiWidget-method} \alias{size<-,guiWidget-method} \alias{svalue,guiWidget-method} \alias{svalue,gGridComponent-method} \alias{svalue,gGroup-method} \alias{svalue,gButton-method} \alias{svalue,gCalendar-method} \alias{svalue,gCheckbox-method} \alias{svalue,gCheckboxGroup-method} \alias{svalue,gCombobox-method} \alias{svalue<-,guiWidget-method} \alias{svalue<-,gGridComponent-method} \alias{svalue<-,gGroup-method} \alias{svalue<-,gButton-method} \alias{svalue<-,gCalendar-method} \alias{svalue<-,gCheckbox-method} \alias{svalue<-,gCheckboxGroup-method} \alias{svalue<-,gCombobox-method} \alias{tag,guiWidget-method} \alias{tag<-,guiWidget-method} \alias{tooltip<-,guiWidget-method} \alias{tooltip<-,guiComponent-method} \alias{update,guiWidget-method} \alias{visible,guiWidget-method} \alias{visible<-,guiWidget-method} \alias{isExtant,guiWidget-method} \alias{toolkitProvidesWidget} \alias{defaultWidget} \alias{defaultWidget<-} \alias{blockhandler} \alias{unblockhandler} \alias{svalue} \alias{svalue<-} \alias{size} \alias{size<-} \alias{undo} \alias{redo} \alias{visible} \alias{visible<-} \alias{isExtant} \alias{editable} \alias{editable<-} \alias{enabled} \alias{enabled<-} \alias{focus} \alias{focus<-} \alias{tooltip<-} \alias{font} \alias{font<-} \alias{tag} \alias{tag<-} \alias{id} \alias{id<-} \alias{add} \alias{delete} \alias{dispose} \alias{addSpace} \alias{addSpring} \alias{getToolkitWidget} \alias{getToolkitWidget,guiWidget-method} \alias{$,guiWidget-method} \alias{[[,guiWidget-method} \alias{[[<-,guiWidget-method} \alias{$.guiWidget} \alias{[[.guiWidget} \alias{[[<-.guiWidget} \alias{redo,guiWidget-method} \alias{redo,guiComponent-method} \alias{redo,gWidgetANY-method} \alias{undo,guiWidget-method} \alias{undo,guiComponent-method} \alias{undo,gWidgetANY-method} \title{Methods for gWidgets instances} \description{ Methods introduced by the gWidgets API. } \details{ The base class for this gWidgets implentation are \code{gWidget} and its subclass \code{gComponent} and \code{gContainer}. However, it is expected that the toolkit implementations have several classes of their own. The following methods defined in gWidgets simply dispatch to a similarly named widget in the toolkit. For instance, the method svalue is defined like \code{svalue(obj,...) <- .svalue(obj@widget, obj@toolkit, ...)} where \code{.svalue()} and \code{obj@widget} are in toolkit, and \code{obj@toolkit} is used for dispatching in the appropriate toolkit. The gComponent methods are: \describe{ \item{\code{svalue(obj, index=NULL, drop=NULL, ...)}: }{ This method returns the "selected" value in a widget. Selection varies from widget to widget, but should generally is what can be added to the widget by mouse click or typing. For some widgets, the extra argument \code{index=TRUE} will return the index of the selected value, not the value. For some widget, the argument \code{drop} is given to either prevent or encourage dropping of information. } \item{ \code{svalue<-(obj, index=NULL, ... ,value)}: }{ This method is used to set the selected value in a widget programaticaly. The \code{index} argument is used when the value is set by index. } \item{ \code{[(x,i,j,...,drop=TRUE)]}:}{ For widgets where selection is a choice from a collection of items, the \code{svalue} method refers to the choice and the square bracket notation refers to the items. For instance, in a radio button (\code{gradio}) the svalue method returns the selected value, the \code{"["} method refers to the vector of possible values. Whereas in a notebook (\code{gnotebook}), the \code{svalue} method refers to the currently opened page and the \code{"["} refers to all the pages. } \item{ \code{"[<-"(x, i, j, ..., value) }:}{ In those cases where it makes sense assignment to pieces of the widget can be made with the square bracket notation. For instance, for the radio widget, this can be used to change the labels. } \item{ \code{size(obj, ...)} or \code{size<-(obj, ..., value)}: }{ Returns or sets the size of the object. For setting the size, the value is given in terms of width and height of widget in pixels. } \item{ \code{visible(obj ...)} or \code{visible<-(obj,..., value)}: }{ Used to check if widget is visible or not. When setting the visibility, \code{value} should be a logical. "Visibility" differs from widget to widget. For \code{gwindow}, like most other widgets, it refers to whether the base container is shown or not. For the dataframe-like widgets \code{gdf} and \code{gtable} visibility refers to which rows are shown. For \code{gexpandgroup} it sets whether the container displays its children or not. } \item{ \code{isExtant(obj ...)} }{ Used to check if a gwindow object is extant (not been destroyed). An R object can point to a window that can no longer be shown, as it may have been closed by the window manager. } \item{ \code{enabled(obj,...)} or \code{enabled<-(obj,..., value)} }{ When a widget is disabled, the toolkit makes it unresponsive to user input and changes the color of it, usually by graying it out, to indicate it is disabled. This method is used to change the state. } \item{ \code{editable(obj,...)} or \code{editable<-(obj,..., value)} }{ For some widgets, e.g. \code{gedit} one may wish to query or change whether the area could be edited. } \item{ \code{focus(obj,...)} or \code{focus<-(obj,...,value)}: }{ method to check if a widget has focus (for keyboard input), or to force focus on a widget. } \item{\code{tooltip<-(obj,value)} }{ Add a tooltip to the widget. Tooltips are toolkit, OS, and event loop dependent. } \item{\code{defaultWidget(obj,...)} or \code{defaultWidget<-(obj,...,value)} }{ Sets the widget to be activated when the parent window has focus and the enter key is pressed. } \item{\code{font(obj, ...)} or \code{font<-(obj,...,value)}: }{ Can be used to check or set font attributes in a widget. In gWidgetsRGtk, the font attributes are given as a named vector. The available names are \code{family} with a value of "normal","sans","serif",or "monospace"; \code{style} with a value of "normal","oblique", or "italic"; \code{weight} with a value of "ultra-light","light","normal","bold","ultra-bold", or "heavy"; \code{size} with a value of "xx-small", "x-small", "small", "medium", "large","x-large", and "xx-large". In some tollkits this can also be an integer, as in 16 for 16point font. and \code{color} which for gWidgetsRGtk is any of the values returned by \code{colors}. [Prior to version 0.0-22 the weight and style were switched. Old code needs to be changed.] For \pkg{gWidgetstcltk} the above should work as well. } \item{\code{undo(obj, ...)} or \code{redo(obj,...}: }{ For toolkits that support undo/redo operations. (Qt and the \code{gtext} and \code{gedit} widgets.) } \item{ \code{tag(obj,i, drop=TRUE, ...)} or \code{tag<-(obj,i, replace=TRUE, ...,value)}: }{ These functions work like the \code{attr} function -- they set values within an object. In RGtk, these are carried with the pointer which is passed into functions -- not a copy. This allows values to be set without worrying about the scope of the assignment. When setting a tag, the argument \code{replace} can be set to \code{FALSE} so that the value appends. The tags are stored internally in a list. Calling \code{tag(obj)} will return this list. } \item{ \code{id(obj,...)} or \code{id<-(obj,..., value)}: }{ An id is a name for a widget. This is primarily used internally with the spread-sheet like widgets so that columns can have values -- the data in the column, and an id -- the column name. Objects can be given an id like a name. For non-widget items, the id is an attribute. } \item{ \code{update(object,...)}: }{ Some classes use this method to update the state of the widget } \item{ \code{ add(obj, value, ...)}: }{ This widget is used to add something to a widget. What "adding" means varies from widget to widget. \emph{ For this method, there are several different arguments that can be passed in via the \code{"..."} argument. When the API is cleaned up this should change.} For the containers (\code{gwindow}, \code{ggroup}, ...) adding adds a widget to be packed in. For the parent container produced by \code{gwindow} only one item can be added. For groups, this is not the case. For \code{ggroup}, \code{gframe} and \code{gexpandgroup} the extra argument \code{expand=TRUE} will cause the widget to take up all possible space within the container. The widget can grow to fill the space. The argument \code{fill}, with values \code{"x"}, \code{"y"}, or \code{"both"} indicate which direction the widget should grow. The argument \code{anchor} takes a value with x-y coordinates in {-1,0,1} by {-1,0,1) indicating where to anchor the widget if it does not grow in both directions. For the components, \code{add} has different meanings. For notebooks (\code{gnotebook}, ...) \code{add} is used to add pages. In this case the extra arguments are: \describe{ \item{\code{label}}{ to assign the label. This may be a text string or a gWidget} \item{\code{override.closebutton}}{To override the placing of a close button} } For the text buffer widget (\code{gtext}) \code{insert} (origally called \code{add} which still works but is deprecated) is used to insert text into the buffer. In this case, extra arguments are available: \describe{ \item{ \code{font.attr}}{ can be used to specify font attributes for the text } \item{do.newline}{ a logical indicating if a newline should be added after the text } \item{where}{ An indicator of where to place the text: "beginning", "ending", or "at.cursor", although the latter may not be implemented. } } }} \item{\code{delete(obj, widget,...)}: }{ For gContainers this method is used to delete a widget that has been added with \code{add}. In RGtk, the widget is actually detached and can be added at a later time. Any handler assigned by \code{addhandlerunrealize} is called when the widget is detached For notebooks, the \code{delete} method removes a page in the notebook. } \item{\code{dispose(obj,...)}: }{ This method is used to remove an object. For top-level windows it destroys the window. For notebooks, it removes the current page. In RGtk2, for other objects it will destroy the top-level window. } \item{\code{ addSpace(obj, value, horizontal=TRUE,...)}: }{ Used to add space between widgets in a container } \item{ \code{addSpring(obj, ...)}: }{ When packing widgets into a group the widget abut each other filling in from left to right or top to bottom. This puts a "spring" between two widgets forcing the ones to the right of (or below) the spring to be pushed as far as possible to the right (or bottom). } } To access the underlying toolkits the \code{getToolkitWidget} will return the main widget associated with a component. The \code{$} method can be used to dispatch to an underlying method call in the toolkit. The \code{[[} and \code{[[<-} method can be used to inspect and set properties of the underlying object. } % \author{} \note{See package vignette for more examples} \seealso{\code{\link{gWidgets-handlers}} for methods related to handlers.} \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gmenu.Rd0000644000176000001440000001503012165556111014236 0ustar ripleyusers\name{gmenu} \alias{gaction} \alias{gmenu} \alias{gtoolbar} \title{ Constructors to make menubars or toolbars} \description{ A menubar or toolbar are created using these constructors. These are specified using a lists, and these may be seen as simply mapping these lists into the corresponding widget. } \usage{ gmenu(menulist, popup = FALSE, action=NULL, container = NULL, ..., toolkit = guiToolkit()) gtoolbar (toolbarlist, style = c("both", "icons", "text", "both-horiz"), action=NULL, container = NULL, ..., toolkit = guiToolkit()) gaction(label, tooltip = NULL, icon = NULL, key.accel = NULL, handler = NULL, action = NULL, parent=NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{menulist}{A list defining a menu bar} \item{popup}{Logical indicating if this should return a popup menu} \item{toolbarlist}{A list defining a toolbar} \item{style}{What style to use} \item{action}{Passed to menubar handlers} \item{container}{Container to attach widget to. Should be a gwindow instance.} \item{label}{Label for action item} \item{tooltip}{tooltip} \item{icon}{icon to decorate instance of action} \item{key.accel}{keyboard accelerator. If specified, a parent window must also be specified.} \item{parent}{Needed if key.accel is specified} \item{handler}{Handler called when object attached to action is activated} \item{\dots}{Passed to the \code{add} method of the container} \item{toolkit}{Which GUI toolkit to use} } \details{ The gaction constructor creates reusable objects for use with buttons, menubars and toolbars. Once constructed, the main methods are \code{svalue}, and \code{svalue<-} for getting and setting the label text and \code{enabled<-} which can changes whether the widgets depending on the action are sensitive to user input. An action object contains a label, an optional icon, an optional keyboard accelerator, a handler and a parent window. The handler does not have the widget from which it is called passed in to the \code{obj} component of the first argument, but one can parametrize the argument with the \code{action} argument. The icon, tooltip, and keyboard accelerator are very much toolkit and OS dependent, and so may not always be available by the widget using the gaction object. The keyboard accelerator may use modifiers \code{Control}, \code{Alt} or \code{Shift} along with a letter, such as \code{Control-c}. For \pkg{gWidgetstcltk} the value is passed to \code{tkbind}. For \pkg{gWidgetsQt} the value is passed to \code{Qt$QKeySequence}. For \pkg{gWidgetsRGtk2} the value is parsed and manipulated. The keyboard accelerator requires a parent container so that the corresponding window for which the accelerator applies can be found. The lists defining a menubar or toolbar are very similar. Each is a list with \emph{named} components. A component is a terminal node if it a) is a \code{gaction} instance or b) has a \code{handler} component, which is a function to be called (without arguments) when the menu item or toolbar item is selected. Optionally, an \code{icon} component can be given specifying a stock icon to accompany the text. A non-null component named \code{separator} will also indicate a terminal node. In this case, a visible separator will be displayed. A menubar list can use the hierarchical nature of a list to generate submenus. For toolbars this is not the case. These constructors map the list into the widget. The methods for the constructors refer to these list defining the widget. The \code{svalue} method returns the list. The \code{svalue<-} method can be used to change the list, and hence redo the menubar. The \code{"["} method refers to the components of the list. The \code{"[<-"} method can be used to change pieces of the menubar or toolbar. The \code{add} method with signature \code{(obj,lst)} or \code{(obj,gmenu.instance)} can be used to apped to the current menubar/toolbar. The second argument is a list or an gmenu or gtoolbar instance. The \code{delete} method can be used to delete part of the menubar/toolbar. The \code{value} argument can be either a character vector with the top-level names to delete, or a named list, or an instance of either gmenu or gtoolbar. Popular usage reserves toolbars and menubars for top-level windows -- not dialog sub windows, or sub groups within a GUI -- as such, the container, specified at construction, should be a top-level gwindow instance } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ mbl <- list() mbl$File$Open$handler = function(h,...) print("open") mbl$File$Quit$handler = function(h,...) print("quit") mbl$File$Quit$icon = "quit" mbl$Edit$Find$handler = function(h,...) print("Find") mbl$Edit$Replace$handler = function(h,...) print("Replace") w <- gwindow("gmenu test") mb <- gmenu(mbl, container=w) tbl <- list() tbl$New <- list(icon="new",handler = function(...) print("new")) tbl$Print <- list(icon="print",handler = function(...) print("print")) tb <- gtoolbar(tbl, container=w) ## example of using gaction ## works in gWidgetstcltk, but much better in gWidgetsRGtk2 ## stub for handler f <- function(h,...) print("stub") ## some actions. The icon is optional, as is tooltip aOpen <- gaction(label="Open", icon="open", handler=f) aClose <- gaction(label="Close", icon="close", handler=f) aQuit <- gaction(label="Quit", icon="quit", handler=function(h,...) dispose(w)) aCut <- gaction(label="Cut", icon="cut", handler=f) aCopy <- gaction(label="Copy", icon="copy", handler=f) aPaste <- gaction(label="Paste", icon="paste", handler=f) ## set up groups of actions so that they can be disabled/enabled ## all at once allActionsGroup <- list(aOpen, aClose, aQuit, aCut, aCopy, aPaste) editActionsGroup <- list(aCut, aCopy, aPaste) ## define menubar list ml <- list(File = list( open = aOpen, close = aClose, sep = list(separator = TRUE), # must be named component quit = aQuit), Edit = list( copy = aCopy, paste = aPaste)) ## toolbar list has only one level tl <- list( Open=aOpen, sep = list(separator = TRUE), # must be named component Quit = aQuit) ## set up main window w <- gwindow() gmenu(ml, container = w) gtoolbar(tl, container = w) ## Now add a widget gbutton(action = aQuit, container = w) ## disable a group of action sapply(editActionsGroup, function(i) enabled(i) <- FALSE) } } \keyword{interface }% at least one, from doc/KEYWORDS gWidgets/man/gdf.Rd0000644000176000001440000000542611406427005013667 0ustar ripleyusers\name{gdf} \alias{gdf} \alias{gdfnotebook} \title{Constructor of widget to edit a data frame} \description{ A widget used to edit data frames } \usage{ gdf(items = NULL, name = deparse(substitute(items)), do.subset = FALSE, container = NULL, ...,toolkit = guiToolkit()) gdfnotebook(items = NULL, container = NULL, ..., toolkit=guiToolkit()) } \arguments{ \item{items}{data frame to be edited} \item{name}{Name of data frame} \item{do.subset}{A logical. If \code{TRUE} a means to filter the output using logical values is given.} \item{container}{An optional container to attach widget to} \item{\dots}{Can be used to overide default colors.} \item{toolkit}{Which GUI toolkit to use} } \details{ This widget is similar to that provided by \code{\link{gtable}} only this is intended for editing of data frames. The \code{gdfnotebook} widget uses a notebook to hold several data frames at once. In gWidgetsRGtk2, the table shown can be edited. Double click in a cell to allow this. When editing, the value is saved when the cell is left. This is done using the up or down arrow keys, the Enter key, the Tab key or the mouse. The down arrow key moves the cursor down a row, extending the size of the data frame if necessary. The Enter key moves the cursor down, but does not extend the data frame if at the bottom. The Tab key moves to the right. If at the end, a dialog to add a new variable pops up. Right clicking in a cell that is not currently being edited pops up a menu to edit the colum names, sort or apply a function to a row. If \code{do.subset=TRUE} then one can filter using subsetting by a single variable. The variable may be selected by a droplist, the logical expression can be entered or one selected from a droplist. If more complicated filtering is desired, the \code{visible<-} method may be used, its value should a logical vector of length given by the number of rows of the data frame. The \code{svalue} method returns the selected value. The \code{svalue<-} method is used to select rows without a moust, the value is a set of row numbers. The \code{"["} method is used for data-frame like extraction from the object. The \code{"[<-"} method can be used for data-frame like assignment, with limitations. The \code{dim}, \code{dimnames}, \code{dimnames<-}, \code{length}, \code{names} , and \code{names<-} methods should work on the object as they do for data frames. The \code{addhandlerchanged} handler responds to changes in the values of the data frame. } % \value{} % \references{} % \author{} % \note{} \seealso{\code{\link{gtable}}} \examples{ \dontrun{ obj <- gdf(mtcars, container=gwindow("mtcars"), do.subset=TRUE) obj[1,1] obj[1,] obj[,1] obj[1,1] <- 21 obj[,] <- head(mtcars) ## replace df } } \keyword{interface } gWidgets/man/gWidgets-package.Rd0000644000176000001440000000624211406427005016272 0ustar ripleyusers\name{gWidgets-package} \alias{gWidgets-package} \alias{gWidgets} \alias{installing_gWidgets_toolkits} \docType{package} \title{ gWidgets API for building toolkit-independent, interactive GUIs } \description{ gWidgets provides a toolkit-independent API for building interactive GUIs } \details{ The gWidgets package creates an API for interacting with GUI toolkits. This package is toolkit neutral. The interactions is provided by a further package, such as gWidgetsRGtk2, or gWidgetsrJava. Some details on the installation of toolkits is provided by \code{installing_gWidgets_toolkits}. Index: \preformatted{ gWidgets-dialogs Basic dialog constructors gWidgets-dnd Functions to add drag and drop ability to widgets gWidgets-handlers Methods to add event handlers to objects gWidgets-icons Functions for adding icons gWidgets-methods Methods for gWidgets instances gWidgets-undocumented.Rd gaction Reusable objects for buttons, menus, toolbars Undocumented, but exported, functions gcheckbox Constructor of widget to indicate whether a value is desired or not gcommandline A command line interface gdf Constructor of widget to edit a data frame gedit Constructors for widgets to handle text input gfile Dialogs for file and date selection ggenericwidget A constructor to create widgets for evaluating functions ggraphics Constructor for a toolkit specific plot device and a notebook to wrap plots in ggroup Containers for packing in subsequent widgets ghelp Widget to interface with help pages ghtml widget to show html. (not implemented) glabel Constructors for widgets that show text or images glayout A container for aligning widgets in a table gmenu Constructors to make menubar or toolbars gnotebook constructor for notebook widget gpanedgroup A paned group holds two widgets with a handle between them to adjust the amount of space allocated to each gradio Widgets to allow selection from a vector of items gseparator Widget to draw separator line gslider Constructors for widgets to select a value from a sequence. gstatusbar Constructor of status bar widget gtable Constructor for widget to display tabular data gtree Constructor for widget to display heirarchical dta guiToolkit Function to select the GUI toolkit used by gWidgets guiWidget-class Class "guiWidget" ~~~ gvarbrowser Widget for browsing environment gwindow Constructor for base container } } \author{ Philippe Grosjean, Michael Lawrence, Simon Urbanek, John Verzani Maintainer: John Verzani } %\references{} \keyword{ package } gWidgets/man/gseparator.Rd0000644000176000001440000000153212034653345015276 0ustar ripleyusers\name{gseparator} \alias{gseparator} \title{Widget to draw separator line} \description{ Simple widget to draw a line used clarify layout of widgets. } \usage{ gseparator(horizontal = TRUE, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{horizontal}{If \code{TRUE} line is horizontal, otherwise vertical.} \item{container}{Optional container to attach widget to} \item{\dots}{Ignored } \item{toolkit}{Which GUI toolkit to use} } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ w <- gwindow("separator example") gp <- ggroup(container=w) glabel("left widget", container=gp) gseparator(horizontal=FALSE, container=gp, expand=TRUE) glabel("right widget", container=gp) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gslider.Rd0000644000176000001440000000723512165556260014571 0ustar ripleyusers\name{gslider} \alias{gslider} \alias{gspinbutton} \title{ Constructors for widgets to select a value from a sequence.} \description{ The gslider widget and gspinbutton widget allow the user to select a value from a sequence using the mouse. In the slider case, a slider is dragged left or right (or up or down) to change the value. For a spin button a text box with arrows beside allow the user to scroll through the values by clicking the arrows. Some toolkits only allow integer values for these. } \usage{ gslider(from = 0, to = 100, by = 1, length.out=NULL, along.with=NULL, value = from[1], horizontal = TRUE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) gspinbutton (from = 0, to = 10, by = 1, length.out=NULL, along.with=NULL, value = from, digits = 0, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{from}{Starting point in range. For \code{glider}, this may be a vector of values that can be sorted from \code{sort(unique(...))}. In this case, \code{to}, \code{by}, etc. are ignored.} \item{to}{Ending point in range} \item{by}{Step size between values in the sequence} \item{length.out}{In place of by, take number of steps from this} \item{along.with}{In place of length.out, take length from this vector} \item{value}{ The initial value } \item{digits}{The number of digits shown} \item{horizontal}{Specifies orientation of gslider widget} \item{handler}{Called on a change event.} \item{action}{Passed to handler } \item{container}{ Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ Widgets to select from a vector of values. This vector is usually a sequence, as is returned by \code{seq}, hence the similar arguments, although the implementation is a bit less general, as \code{length.out} and \code{along.with} are used to compute \code{by} when given. For \code{gslider} any ordered vector may be used if specified to \code{from}. Some toolkits only allow integer sequences, see the respective \pkg{gWidgetsXXX} packages for details. The \code{svalue} method returns the selected value. If all values are specified to \code{from}, then \code{index} argument is respected. The \code{svalue<-} method is used to set the selected value. If all values are specified to \code{from}, then \code{index} argument is respected. The \code{[<-} method can be used to change the sequence that the value is selected from. It expects a regular sequence, or if all values were originally specified to \code{from} a sortable sequence. The \code{addhandlerchanged} handler is called when the widgets' value is changed. } % \value{} % \references{} % \author{} % \note{} % \seealso{} \examples{ \dontrun{ x <- rnorm(100) ## our handler plotHist <- function(...) hist(x, col=gray(svalue(sb)), breaks = svalue(sl)) w <- gwindow("Slider and spinbox example") tbl = glayout(container=w) tbl[1,1] <- "Slide value to adjust shade" tbl[1,2] <- (sb <- gspinbutton(from=0,to=1,by=0.05,value=.5, container=tbl, handler=plotHist)) tbl[2,1] <- "No. breaks" tbl[2,2, expand=TRUE] <- (sl <- gslider(from = 1, to= 100, by=1, value = 10, container = tbl, handler = plotHist)) ## update slider using [<- sl[] <- seq(2,50, by=2) ## other sequence: w <- gwindow("Slider with sequence") sl <- gslider(letters, container=w) svalue(sl, index=TRUE) svalue(sl) <- "m" sl[] <- LETTERS ## can be sorted via sort(unique(LETTERS)) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/man/gcheckboxgroup.Rd0000644000176000001440000000646212034653161016144 0ustar ripleyusers\name{gcheckboxgroup} \alias{gcheckboxgroup} \title{Widget to allow multiple selection from a vector of items} \description{ Widgets to select one (or several) from a given vector of items. These are a radio group where all values are shown at once, but only one may be selected; a checkbox group where more than one may be selected; and a combo box (or droplist) where initially only a single value is shown, and the others are a mouse click away, } \usage{ gcheckboxgroup(items, checked = FALSE, horizontal = FALSE, use.table=FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit = guiToolkit()) } \arguments{ \item{items}{ Vector of values to select from } \item{checked}{A logical vector indicating initial values.} \item{horizontal}{A logical specifying the layout for gradio and gcheckboxgroup} \item{handler}{Called when selection is changed} \item{use.table}{If \code{TRUE} a table with checkboxes will be used instead (toolkit depending) so that one can scroll through the values} \item{action}{Passed to handler when called.} \item{container}{Optional container to attach widget to} \item{\dots}{Passed to \code{add} method of container} \item{toolkit}{Which GUI toolkit to use} } \details{ The \code{svalue} method returns the selected values by name. If the extra argument \code{index=TRUE} is specified, the indices of the selected values is given. The \code{svalue<-} method can be used to set the selected value. This widget is a cross between a checkbox and a radio button group. As such, there are different ways to specify the state. As with a checkbox, the argument can be a logical vector indicating which checkboxes are to be checked (recycling is done). As with a radio button group, the value can be a character vector indicating by label which checkboxes are to be checked; or if the \code{index=TRUE} argument is given, a vector of indices for those checkboxes to be checked. The \code{"["} method refers to the vector defining the items. The \code{"[<-"} method can be used to change the vector defining the items. The length should be the same as the original, although in some toolkits this isn't necessary. The \code{"length"} method returns the number of items. } % \value{} % \references{} % \author{} % \note{} \seealso{ A checkboxgroup is one of several ways to select a value of a set of items. See also \code{\link{gcheckbox}}, \code{\link{gradio}}, \code{\link{gcombobox}}, and \code{\link{gtable}}. Methods for gComponent objects are detailed in \code{\link{gWidgets-methods}}. Event Handlers are detailed in \code{\link{gWidgets-handlers}}. } \examples{ \dontrun{ flavors <- c("vanilla", "chocolate", "strawberry") f <- function(h,...) print( paste("Yum", paste(svalue(h$obj),collapse=" and "), sep = " ")) w <- gwindow("checkbox example") gp <- ggroup(container=w) glabel("Favorite flavors:",container=gp) cbg <- gcheckboxgroup(flavors, container=gp, handler=f) svalue(cbg) <- c(TRUE, FALSE, TRUE) svalue(cbg) svalue(cbg) <- "vanilla" svalue(cbg, index=TRUE) <- 1:2 cbg[3] <- "raspberry" ## use a table to display (toolkit specific) so that scrollars can be used cbg <- gcheckboxgroup(letters, container=gwindow(), use.table=TRUE) } } \keyword{interface}% at least one, from doc/KEYWORDS gWidgets/DESCRIPTION0000644000176000001440000000314313652210053013563 0ustar ripleyusersPackage: gWidgets Version: 0.0-54.2 Title: gWidgets API for Building Toolkit-Independent, Interactive GUIs Author: John Verzani. Based on the iwidgets code of Simon Urbanek and suggestions by Simon Urbanek, Philippe Grosjean and Michael Lawrence Maintainer: ORPHANED Depends: methods, utils Suggests: gWidgetstcltk Description: Provides a toolkit-independent API for building interactive GUIs. At least one of the 'gWidgetsXXX packages', such as gWidgetstcltk, needs to be installed. Some icons are on loan from the scigraphica project . License: GPL (>= 2) URL: https://r-forge.r-project.org/R/?group_id=761 Collate: aaaGenerics.R common.R toolkitClasses.R guiWidget.R guiContainer.R guiComponent.R guiComponentWithItems.R handlers.R ggroup.R gframe.R gexpandgroup.R gspinbutton.R gslider.R gsvg.R ggenericwidget.R gtable.R ggraphics.R gtext.R dialogs.R gtoolbar.R gaction.R ghelp.R gtree.R gbutton.R ghtml.R gcalendar.R gimage.R gcheckbox.R glabel.R gcheckboxgroup.R glayout.R gcombobox.R gmenu.R gvarbrowser.R gcommandline.R gnotebook.R gvariables.R gdf.R gpanedgroup.R gwindow.R gdfnotebook.R gradio.R gedit.R gseparator.R icons.R gfile.R gformlayout.R gstatusbar.R bbbGenericsANY.R zzz.R LazyLoad: yes Packaged: 2020-04-25 06:52:58 UTC; ripley NeedsCompilation: no Repository: CRAN Date/Publication: 2020-04-29 05:27:07 UTC X-CRAN-Original-Maintainer: John Verzani X-CRAN-Comment: Orphaned and corrected on 2020-04-29 as no response from maintainer. . And NMUs by the CRAN team since 2014. gWidgets/build/0000755000176000001440000000000012377442527013173 5ustar ripleyusersgWidgets/build/vignette.rds0000644000176000001440000000033712377442527015535 0ustar ripleyusers}0ED W7n !mc+6"%Є)v4󸝓{!!dBHc(3xQI}8U+U^Nb/y!t;j.9wh.Dl)`Nj% WϊA},klYhZ3+Y <ȥ~-tne"^)[qTk4K,2Pa?Kb"C4KN Q ةgWidgets/vignettes/0000755000176000001440000000000012377442527014104 5ustar ripleyusersgWidgets/vignettes/Rmail.png0000644000176000001440000004670411406427017015656 0ustar ripleyusersPNG  IHDR&{9 pHYs᣻tIMEb1 IDATxw@SWsI$pl V+Z+uTuZZjmZx}"ĪSBT 2?M#ɹuǓsMB!_?g"fXOGG'=.;; :a#̭S!w>!! TQ= 142yre|~k}ghkhޟ"9n⍵dRPP9CaptuAA՛sQcBXsS6xĸ X24՞g$Jԉ|tv=P-aܔr:.` /L:H$})3qu/ Fhb%B(e&dۼ}O[A `&zZ\CJ0ؙ+:,9׌rޜQm4TM:$D\LI!]m*IӦkR(dDT^YUht"&3 F.m*3ٲӜ^‹P3y͸Zf[Xr t1(Gy\CiiiȀ{qޟKYI *hm7"2LM$6S`kSFƦzQ]ugB>fu{(*̷BL6fҦ\B~?FѠ<`C8;_rfe*uKr+4Y"Q1]*\p2 $eܾ45H3 tu4BgϋDl0 dMD"Aİ.fꕖ%7Yux9l m_<V♡)EC`Q!K})AW߈ PY }?ll56~&fC]p [b%s:,e׋.H>7y":F*pw [";?ryhTrgtY,]Kk;'L-u6訋B谞"46[age{~;rjԐQ5b0dc}GHd:DYnq"Ȱ95ddXNfeQiݔr:o=u#HaKy?S k6/"&B(;'ܺ@,ȴ3Mciӛ[ZGf&S(N1XQ~g|.xƏ4sQ啕G#N}<~ OchR/;\kт\==SCPuBQ׮kk+Ik]؃ 8ںQ=J&F|lm %d *FCT73R44ZɸOc0_^ YWUCia%tvG[SuK'y8uE!^1kF,] k;dn PEe2Z[;.,&k32?"NǺR d:728oi:^1mR"nmCWT>Gt&B S{>L&!Lbsm1?#S L n 1WBٔrБF6!DjGYYk𨀇222,ΫGxet9\ :3jBUYS.'6(cscЁáF9\K76׶oc7ꟚH(YYEY>7b-o#B~ݏw$?!\6]uKur@0Kk;gav,Y,]Tl%?Tn$ Lb_fs,L QԷs#+ u17 CF$g]760g]H$U׭߅v >3h ʪF0A!PA"(d2YjtM*B(nP!T[]2VWUkx9R4(xJiY`'w'w<$vrta u!Z[ 1W}>4#wBu%ɚ,6BoWoͪj504鰥ðAu4?w&ut j<\?/IFU_1mr.bsuvn:-7؊A"Y8~oH$BLm(QNjHJnNFp2"lHWt6V[Sr#D5gɡj5Eu |] {DzQ^x#DISdR)~aFUTV(T22,(%#{÷ߘ<.262Xv])d YZi(FOXzF aT!$JR}u z,-51dHɒAu6qp=nੰW]ʞS}I%cGJwtqpDpB(n1l[h:O%iCFT[].i#2^MF}!J_K*&ARH4 ŸPCZR&e̛߱uC1CݺIӤjj*WvMg)s}g]|ƄʦR(t1/jD"Ę͠"RY}]͝ӧVYJj1;s1Hd҃GBFh?xG #B)ټ}n]:_ݶ.KEKǍt{VY߾BR"I$be ]mE1͜1W*l=&fyQ.kq}HKMKV_wK>yaV/;t訜tgyG8LhL&L?gs:M(G/|ASAN {U DPRoa5k:C;)%gc# cGt Z4&ƆϘk7,+<~w{mK JTjjl`%’w\+J3uAk^^JۡLB+Cj֭EuK w@|V^eifojQz^/*Y̘ʁTa(F9.>~q ,rz$7i>2vܺ6ʩ*4W6zLU4ҲP!JJfqb4ۚ0tHT]]_P.(.(>W&C7o߹z톁6ʨk7NVj3H{q61446U]wL ꚚwR.\laekfa_RqA[ + s--D*y_p'%MFpU|>UY65,bqKWmWA-=~꼻C.b x&Sc#:aX5Qݨs;YKeҸk MNwh_:>Q`gή݈]078}\UI[Y&+p;\9L B">Cd҆ee%5ՕM|Xamnacdb7׽x+yZX]Yj8z\3 k#-mO?-xgicU|doo`TWVdR&̒f764(T h7bUOؔ@ TVUx7E"PwzO +1ſ?fsoU#+47h)BZ:"L+yZT_UQ.ZXYZ۵I7olxWRTPYQ.hi035Ԡjox Bk`ԛs}VZ|N~cɭb`hj`hˏD&I477ru4:CKCbqkkZZB4[[T [_R'!65P_+ɴu,]:CTJ)d ]]=~cD,֠j::LM!dlbd֛YE"!aC[[GM?t N}}0&KdVl}bed Eadҗ :,6_KFt&K#t!}(4o:[Z!`׆ 4A-X2dpGrz(Hq1pօXى מ>ydeӏpr::L0:9pplf?E~u2͹):0Eo?hg: F.vB8,-Sk0!t }ݽ:#/66M LxK B!r6yz=BYnҳ5kz7;ʁ8gbbbFi),+,,Օ:;;?~:oǏ l;)e߾}vpp믵Lz(۽{544g?){fAR~W777 믿ݻv<5odffΙ3F$^ɣ >\unn.xxBR)ǣoo=M})++M^Rn߾zРAoܸ1--ƍfzWeddD+VMM=ܺukFFT*uqqYr*e_uiiq``ԩSa@o9ʞ+:8(;-YOr@yr9_mNCa#Fȑd#zJLۉ:#x|[!r9 @Ν;vȑiӦD,@霟_:@$ʤRis3"(JłL0b c,osIT*D tN UV'':$EbihJ[Zt$ Z0$ |TR+fͼjnn&HrBZd2L*R5/21LF+tM j.ɤ-T6E2LDRT*#IZď~ئ T,DrkuuuWY,*))_\~śn!ikG*xF9---GQQ};_TT:::Nr%G1mڴ3gX7֐cNG- !2*#޳sɓ'"l\r. +fHeT"svvVg/"5oGLխZs<<)*Bkh6r={~޿ߛa dviX$J^=i??yc`[^)=ՌVJ%H5@!!EiD**l-*'C*CUW mY|kdC/^9vYD*^r[5 ĉ^MMMFJ"4L&k7 -9Yw7&ִo1 #˗/7%""B>ehhxԩǛXYYUTTȷ:qĐ!C X v(RQo;ܹsʕӦM 9yӧO&$$Xbʕ= ۷oߥKX,6oѣ۷okiiῶ{~-??߾}_2I& 4(777..u۶mړ&MP,"<<|,Ñ=B1̺+D"@ɓ[n۷!駟.\pʔ)A&eddǩC IDATD=={{{|ɓ'$kժUǏǷz/>PMueB FC__T*B77O>}_X___IJN ?ֽ2L&&O,ɄB֭[׬Ys1"pBcܔ|njj_ 6   >\͟T]k׮D Je2---/\0sL .\`aa1p@ :?ׅc_555;{{{,J?~J_lse9+ҥKO"xaPԺn:fVSSd2׃>H$)4ρOrr ՕsNpp HE|Ǖ'NăV#GL8166 ŋϟ?|?cJJ@ hjjJJJ3gN?lٲ>==](޽{wݺuj>>2߿mmmKK˗/_.ϖD"-XCK2wX82ǩq… QQQׯJׯ_|1o<*?zh"?߽{W*:88,[ӿ@3uԆgbbdɒuֽ~e:~z'''LfeenݺoFyܤR?,a#zZO]5YOo r@ Bt9> 3͐,&b')zٳgH> 4'_$@CQ!B#䰔= 0ۻE]kxCzCFEE(k[huzz%J5jÇE"?z~ZٙmUtwvXjժӧ;;;_ztÆ O2dǃr۶mk }Ѩj޽=sYYو#I曇\ښL&kkkO8ʕ+_|ŤIZZZZOο[UU\r\\\\kxxw2W_eeeݿ_ÌEoGyܹ6l6]SSfEFF2`D|睝544,--CCC:~ >G4sJңGZ[[S([[C98ݻwӦ4N{zzō=`0ӧ㥫 d2@[6[}֭3ghiiO&&&'N0,((u޽9bee%GqL~h4.tҦ&y>ϻQTKK˰0yClll9rgϞ [[[ .J?궟2 ! N8gϞxC믧O~m&7nܾ} R:#>f/e{H$/_^`M駿KtΝkhh^x1;vlΝK]vɯ:eʔ?s̘1رcݵ%%%vvvcǎ ڶm[uuuqq%KT^qVzϞ=t:}׮]Nt?CBBV\>uΝ;|~dd/ҍ~ 2&++K [NرcG}}˗^;v짟~ ۸m۶Ǐwncƌ?KJJgJiӦ3g3fذa\ogKgeX-c?O۱cG||[kall0H$ϟ.**!HRra|`iiyEGG'X0 KMMuwwW\_4z5kL6 OOKKꫯHݿZSSS>6lؖ-[&N(oɓM渹UVVΟ?aۺ:7p@y ^ސ-Z__?++rpptqqdBP[[[  u &\reҤI=~?mmm?RQ4|~ʔ)w֭['Ot͛SSS_nG;v妧M]]DJ~@ ޸q@(:⼆X{JN ?G9<{'?Î;B?O"?ׯ߽{7̙3HI7; v^FhiitR/9;rرGDDBN 0֭[oߖO)E ۸qI;~i``^\\S庺fddtu+GGǤ$D~R:;;'$$OWlWbbWׯ/X… <o׮]a7'''ݴj*ggǏGGGO:Zz?(?ŋxo޼s疔_4z7Z扵. yQ}z[oիWGGGyyyD3gGGG+033sΜ9_o'ֺq^k+))i߾}z C9ammm}} 644Yyb8;;{ɒ%i ]ÌBCC̠7zso=z&N'WW pu덹sΝ;v%LoP&^ @ONgzY9} Cz2͇ B!r @!B9naɓ'RtȐ!<(oy;<ñoڬtRGGGww˗'''CoS̀w'$$Z늟=<< ) !3j(}}}GGLjlU>~>3333fٳg5M*_߿ojܲe=~-44111sss޾};kvJJJ|||xx8سgGqYrJ''v_k֬innV;vcdd<۷geeΛ7/66V,%BKvڱcGQQĉ{9x ;tЯzi{ )**͵O~ 6޻w嶙xMΝۻw_w}⊊ @ xϞ=#m2x]9n޽nݺ={\tIq\ܹs'MWZZk׮ϷD"yɊ+Ǝ+OLKKS=1aYrg޳g… ۷oҤI nvZ￟;wԩS<v_dɓ';mxWϯcǺ%%% M6yZ]r%00pӦMgΜts'Nܻwƍ>_Ν;[XX$''O2pj {ڵk3f̐_/_>a„iӦ]v-,,رcsYhӧ8o5a„{zzʯn3gΔ/RVw@@ݻ+Wybrw522R \.VOO$M;MYxJddCOKKKe=9vتٳgV^o%%%cǏ999G fff/^P9\\\=zXMM8qڵ&Mjs'NS[{FŠ|=<-Zh̘1k׮=~8k x<ޱcDŽBall|luPAK.7~NQ롷gO/Z[[544dϯ+V 8X,yNOόs0&ֈDbV펛wx$)^fƍ?Cݾ}[yMR)lECBBN:enn~Ց#GgWt)S߯8斘؍ 0ÇwQZBB‰'>coo CowY,>hddCy:>@ݺu룏>kѢEt:… eee7ȼJ//ɓ' SNBN'խ[oo߾-(x x׺w&LLL|~QQP(411A GIR3}b))++Kyqʕׯ_oM>>%KT9 80$$$/// &&fРAG}Zpa@@@nnX,͛ׯ_N'/99y˖-Iq?v!))鍞7o4hPll+m&9Zti```zzH$JOO_ve˺?)233ڬ0t_~E~!4v;v(н|򠠠 y)k7nLKKkmmmnnqƬYEFFF7oT6͚5+))Z7{ .nj;f̘G BPXXXx!˒o{̙׷y$C$+"""--mK!v{{ٲew+WO>3##E\`l޼?pvvVdook׮:@Ix2]611oҥK{_~CzzzDDɓ67 ?ŋx쳙3gnذvaÆ>|xǎd2t'˒svvtҌ3WZNr8e˖)^Ss  TҮjϷݼya„ ;wܸqÇ aGQֵ':%%X,/^r &\p@"8O.]ZPP sssW^=o޼Qv_m?GDDL>v卍+V ܨӧO ϟ7ʂ{aqb [aMx B!r @!} != @# ңv6}!B-H#GL0TOO?%%X,V75r=^uTT(BYn]BB/_VVvi''׿ZT)h{SAAAOF)ttddd~~>N-^uJpU115xfs(r\ggǏwNLL̨Q#"";vcdd|C?z|:ehh<^^^:::QQQ!9y:a2@ ([nnnT*2,,L~! bkk{Ŝ###i4Nɉ=z4`0ӧO|![[[ bmm}QŢaUwt?޽{ɒ%۶m;qӧOq߾}x~嗋/Y!>>ݺu%%%{tʕ+6m*..>sãx\|y6mjhh駟/|wiiiccΜ9#9#rw@@;/_|U<رc?Sxx8?vضm;v][[[RRbgg7vؠm۶UWW/YD/?uNժ; ԁ aiYҒ4xp\|x/OaXgΜG;v)兯sݕ+W޼y!4qĵkN4(&66׷ Ff͚iӦiii_}Uvv6BHSS3??DٶJUa+>￟2eJt77[N<{ҥ͛7X,V^^)&&&|>_'NwŖ-[ܹeVQeuuuL&~=r+9=4ҐH$'N4<J㖕122jiiyeE TWW# 555fȡm#HBk֬1cƐ!C<==z6h*&]SSFͺxa&J:LK0Y17VEZ 9j}/L&oذƍ*'Jy<^<޼+RQ5et111111NNN!!!bdP>~*: qobbJEEvf}}|Ǐ׼}Ať KIDAT)++rTzkFF...AAA'Nؾ}{9!!}}bbmbbWb&&&:::SDVQ͐ͭ .cƌE"QjjW_}mPPPFFH$ \bEׯ_qƴ7n̚5 _vDPXXXtR<͛m=ږ-[ܹ/NHHhnnW^MLL_Q'88ڵkBɓ'ӿdHjժ懲NPj{9W\  o…×_``P(ׯ7|#F˗ץƁSNmѣǭ[fddHR+W&Ls΍7>| ((H~[te2Y?6nܸ_~%88855U*]|-[)ȑ#nܹseeeO//~-000//hƍxy󚚚Ν[RRbnn~/{E]/(..655ݰaÌ3:-BYUtC^D"144x-Tw$<>/33:>do㯂lss{Bw7:Y5@/} i'<rrކ?8r-L1L=Hr%rʐ)P(6667nlmmF=, N}oo##|>̙3AAAO~Ϳ^w9 ~wތ#FrDClll(#GW;z5СCxȑ#ϝ;ZUUǧe!2a4N{zzō=`0ӧWVV?ehh<^^^:::QQQB4.]Iȑ#VVVP "; l...T*UGGg̙ `0DX,F]xqȐ!t:&44F}>~% 5P=o<<%<<֭[w177={&%%_diig3j("BBB-ZԾhX:4(11Q TUU-Yf;::*L>_966bEGG Ls׷̜9SuL&3119zhKKKYYٗ_~em466?+W]|Y^hCE&* lߟߗQB7D&Id89(G,?~xƌ~~~kVss|&*lHӧ̙hwrRi) v@^.[,,,X 'Yo:C䙨n4P4sX,VJGGH$A$D"{9D"fLg||ݻ3obŊ>)J; n4PTB@ D7p/Gb0QUU%WquuU=Sgb ~4cccHa*2t~ʈ#_i?h4d2Eʕ+R "5+:} vjȑ mLX!Hg̘! sP(LNNߵ>u~[H1+H:cƌQY*2sU77۷o >U///|׵kך>loo:uƍ555ϟ744ekk& lmmթ@*2QWh`^z͖>ڵiӦ W..&&&V'p&666Vȑ#$mAB?!Tȑd cǎ隚Fp~ҥѣGkhhhiiyyy=|Puz~~ T*Jutt?K9x𠅅;BDE_u={J׮]0a=z4<@9ΐ-z$ѣpn333sΜ9發exaʾYx$}+9=4xYϤ}m۶K,Yhѻ0LHx@5aFFFfffNO8O>)((066ꫯV^2(>ȟ9;wܹs{C&!B9 @B!r9 r@!B!r9 r@!B!r9 r@!B!r9 r@!B!r9 r@!B~a=3@Q2„2 `1f6o@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r@>J)8N)51N9j[6%nIENDB`gWidgets/vignettes/addToolkit.R0000644000176000001440000000000011406427017016300 0ustar ripleyusersgWidgets/vignettes/gfunction.png0000644000176000001440000010504611406427017016601 0ustar ripleyusersPNG  IHDRmN[ pHYs᣻tIME-/ʌ IDATxg\YgHHB JQ(AA,*uPTZx,ka,*( T+(*(6BKH p=½sɜ2 b #A 2b]p|\5q[fvw[|,4ALj_@k( @GBT_- ڢYT?q)Бh mQRPP C]i8 tDBY fjlOqW HhP|JmxTh +'l ߠepGQtZ;E, T*5!1c5cj[otM0> E?(:!{Y\>]Der"RvY)LUC \x !i Wct4t(־FGmIPEOQuowѱꮙy(ix$i6^)ү/\uP(FBbk:P%O2u"6Tm5TŠSG%5yt&Gz;rru4zyb7/?ӣHm#k/4E䵩Gt5EuPE*s]4Vg<@ : ܀on`\=vO!cizx2xXxg؋((S&.Ŋ'ps4q&rOҨ[v|:2?kbowGcߕ/ҚQ^w҇jETU%ߩ5\liˀSU[׳(tC/ׯWw 9/htXoLߪB5*z ٍ@P idKQM̽M b7$֦F|kߘ9"Ӷ'&K6 |&@u)JaP}~FU)ROӴ53LE -@ٌ H}Roj[ nF6:9hڸoİx]HF)d>|70VBj1y*MAE?m~TKk~X`˂꺮ZA}5oj~X!FW(t2(OWIu[l]QuzVo^cYSSmccZyj}7Ku}@'E_ Hjze7yRS ~=˃)2)z:ZQҧFtOߣw7J~w@$@&tn|᷄ 'rv  &6KSOQ0ʭ`]U%qT> -4UzsonJebтKtJ 4:e12XXfsCmsosdR0$T:_ף* _]t*iƺ_N "7wshU{y]?Jt(JiQ RkCce[ԦҸD AQ-g?:M׳8Β?Tcj (|CǫjS}pw&\A _E Mb&"R HtT:Jg /TϏY/XQipyEL B%<͙ š3_U[tZ8pj6~`]b; /麈F @{bqY-zii}|rKj%t&mo} 8%TQN=H$҆ @9g+}㳇!>!QAʋs#5?T|˒-SgcBT%ȍГ̫|6i`\\ȩgޢ֥ӈ=3gt~Ƣ֬"noR z 2DfWOAezZ `Y (WQs2uT 7,XOFRQ*UQ? tx53j>UqaEͻPjZU>~N E&R &j7{H|$Y7aI(5~x]6eR"jBP`18|^TQX2IX)i,!ߨF7D"XOˋM|6 .=>G5mƒkT5ALf05hjj,M݆rQL^&WFTړbkt3J%L D*75(슢:+ őOW4 ̙\Q#{[T1:0et ,͢FPjj>SCJW5ԩk5 bYT" Nwn|:Cgr] 0Թ uF7]y<ELi`)#`iiN';Y:VEP>\6Nj0Z( A:"tu ,tEthxG: u F#h=4A&fZRQw  m }8菶st@TL6 !J+++@//0? G(@@f?K[[`X[[oٲtss۱cx (_bqddM'M]WWp˗6l7 ŋ{{ܹ3ftޝFYXX9rȑ#p߾}{왚 ~ҥK̙CL;wҥK;P0`áRXd2y<ޔ)Sq1 ssC뉉߿:1bDNNΥK p8Qs||IՓJR(seN;G7o\ZZzAߨ͛7wXmܸqΝܼyݻ={?`Ǐߴiӱcjkk?~D?//_ZXX ><88x>|(..ڵ ovrrT*}?0sLbsff&2q[vb{g<RKNNҥKNJJʴiP߿?gckkk_@`hhX[[ H~7JJJZvmVV2==zSwiFhiit6667o?|w|ee]RRR;,8EDGGȑ#[`ATTT qppI?|P}uqq\\\>|HX Ab;O>522'fq8j8 ȝ;w\H$zu6zH4s\qBXZZFGG9s^[[+wƍSRRjjj^zvرc]fgg^ʍ euqb1 <*GYfmܸԴO>3glll<p[nD̅ ߼yڵkuuuMMMw?>Q>==}p|iqtٲe :u*ٳ---{t^f̘<}t6=}PR>qDȭߺuttt455ϟ?iҤ7O<9qDڝϿ^##^ [wWaaWF-]4,,LUV-]ɉ'555555 rرv'H쬥bLMM̙s%ł]-@tRTLJJw}߼ysݺuFQ4##㧟~sΎ;d6j ˖-+..޶m[^T/҂_8kEeX5554b8 @iii׮]+Rcǎ4hА!C.\0~ֽ%ϑ#G q+z^paGh1Kz@~ %</,,~H$X)&&fG[[o}!11ql6i|>qSIE) 1x<}}}??v ''' 7jԨ5kjjN<ڿ^-,,=>fXt:NG;eʔ?}SGGf0 66V*((,N۷֭[7oݻGihh,Z .];w+޽{wɭ[&$$( Kw;wȑ#'N899ۿ~:331<<3!lٲ~o盛;6888<<իWyyy]v]x1.yM6={V>*kwU(@{ȑyyyve 5u pŗė^dVVV2LtXr>>/_NII  m@gn̟?ӦM BpÆ k)߷o߇RTK.mjj"cׯ_oeeph4͛7[=s d~"^g0,SD^D9Bqtt\lى'n޼uVlNWa 9oF}ZP:rիCCCo޼  /_v _ Ah_`~ Q8 G9PR./:aϞ=k׮-//W?7… Ĕ> /]]E|8|}S'L;f̘Q[[|F~l{{{AbqTTT\\\G⢭ PSRR ^޽---l68QA{AAΝ;gdddkkfddgfgg"ҭ[7{{{///777]]]pQ&Lc8p~{չs爉G~fÇ\.n5>oO4))i֭Ν+..nlllll,..>w֭[B!xQE,Yrzj„ q(FEE/ɿp;{Ǐ?~|ټsɓ'ԬN<L@vJJJ3b+ED xyyunHT۷)|̤)t-qUV:?t12===={ᡡr=< k*v%Iddd޽Y,˵ۺukCCVի͎;, 7(2L,v` ]u&/K⫦Hb~\FOO[nnnݺ׹Q>?gΜ={tR4 ?\.W,˴gAvڵzjAѪƎRXXXTT4jԨWTT(ӳqwޅo 7ovZZT*)jժ9s̛7 !)^tiXX6߁k]]]&bwŊΝ۷o_YYYIIɁΟ?*Hh4رcA\\\bbƍh?8p`ĉt:x0LUL^WaaaΝ۵kWYYYyyCCCj{M_!{s@MܖjK_ȓ2m4tԬTx;,MM͏5AW̩")-[\xvZ@+H-[f Evjjի/]uJJ?1 ߿ S+J322°O:<" 7ܮ{~o߾XLZv-/IJ T\\СCnj/k - yBSn*dW^SN:.tj?neeneeuWSS |822R"NNN_lll H$555`}}=KPR=&''^411ۃ ϟ?&>---?4rH*> srr999*_bMMMyfff644466fff,X2=;wN4Ia􊎎>2L==I&ݼy*nWV!;u5k֬]v͚5SfFmu[6mZ=|h;;tАWWW "JSRR&LЀ=XQ8AV]]mkk *pN0GU6lXPPVk.]rsst=jjj V6][[+odc۶mCEQ4===(((<ā zl6@ ղC <榩9ӧ+2$r7mܧO`UxQ555e"iݰԾ}(jժ-[;N OLL\x@&ɓuuuǏOR[t;IYr_"迊Ž (E|Θ1")) D|0y}Mq8wbbbӁ O155ׯq_~EEEDQFQD$%yeAy;v''X͛7֏;vsYZZ*ԝ5k|8p >rۢIʒJOH6ѷo_ ׯp84(%!(]lϞ=_xg%cccN5fggX+g!J###T$544>u[l]DB6Nطo_DDDbbBTTTܽ{wܸq- 600heʒb ljj}%KA666.\3ge``p5$ac놄566֭[3gv]YYYUUo߾'O.Z.Y$,,,%%>}U'NLMM uuu7npww6lѣU_%o]ӧgdd`r|||ܭ[ڵ+99YfM)SGhq&OV[[Ϙ1#((Un')Ky\ 3ҺuFR[ly򥑑cc#FqT*577_x=<<͛7R]#T*MHHظqcnnnnBBBΝ=mvE|ɓ'!!!RUdAAAXXXZZZ]]u@@q{LK ۶m>rppXhl2 vm bll{D"7LJKK pq @{…;vdff(jggpB.n'/K+UVVt@ WGa(b TOda#^ ӃweD"ř3g+#CQraDlIʋd(o.~pRo__UNrm%I~\m~@[s#.Ƒyfd$ǬU Yٳ2IFɅI*bA(/FE$ԇD9׍EGٻw/,܅8 @ " |=dee>/ip@ЩQ2ZqfAQL M<{lʕW\J[nU!x55JdݻwGGG(jff6c |!KKK,ŲgΜٶm[NN1b?lllbY111&&&AAA-jqJ33/\__J+7oތ9@5Ç /޽Ν;B˗/wssîq]h_>|0v!C?|ԨQ 0;~x (;` Qegz"k׮xrٲek֬iսC[jkk߻wv\*~o߾4yY[[;99aUJiiiaaa-%Kܚ@*{C\sXXڵkt:ׯ T\\eJ_a>}:**,KӉI(?m՗.]bXx}_(@'m+HNN&FPM^Ç'n'sFws%7D^ŋM!/\JYrT*G<>J֯_`0ZLf]]B A@l*l}1LU@:1}]ev6Tܫh___b?733v<33g3yYCCC[rrrU)bRiQQ… }|| DY{sI&);LWXb}#!##iȑ<9;;9so(3l6pB!y?חBCC՝\.)bpiWW׸8b`YV*CEEݻwǍ'1Z`g`'j"/T*ÊŮgR̩^ڷo_DDDbbB)U]]]CC Fc[df@T+hgyާ?B}zFF*'++SEnĉSSSBa]]ݍ7݇ 6zhUʒ۝:uիWBaSSӽ{|}}gΜ\֭[wڕ,I_}˱jJ6m`7%n:T䔔?s?.9m۶m۶Acccoo`l) !g^vY,âE:m;gΜ7޺uK*ZXXL>}ѢEx%׼j*H$DKKK[*`Ejkksb IjET*In:WWW\_S.]}_tΝ;5je0QQQDcݻgϞ_~E\W'00PVuE"bH$b16n#depU7DR`[d$,R"wֵH}-Z$WL Çwtt,**JOOohhXf|H&Ƥ.\pʕ/_vW^EFF;wNF 11122СC;wY$-%)թYzԩSeNzCŧӈ#22Ac*1drC$e ŮL$"f"TE2֏9BA) yyyX¢}ѢEnnnؿ~:&@ ~ ͛7oTN#?~}ၭS0q^|;,ƍ3g400`{!tp82益wڕ >x]lAnmmml"+++[%=s挓ҥ/RR$vI'NsNUf/ 8Ǜ 8ǻâpmwxb۷gffBN?3Lgg5k8886,<<t^NKKW$DDD8::(z֭={c$v'Mҭ[+VoݺUfɓǏ?o޼Fr$111֭:t(鑑N¶e Uu&K~|޽)S(nG ܹS^!]/^888aqttG_kEKnWk$gE'O|C@U?.%>IU644d2zzz&My&%ڹsI,K/fdd4559x}a8ɓ>fN ?utt什/^500 fCx< 77#Gl޼ܢݚPӣG`<+00pϞ=ʖՐ%]~Muuu#""BBBՊ}J|n+TEXfbo2#ǎ[re||AYfLMMGkׯ_QQE4`X[[>|8!!Iyyyd02؛!غVr(zyy^ \r8je"%Uglȁ7(2jԨ8c766_)dgg۷/"""11Faw7N&Mf1;;HYd`K3uuu @jjj%v[T'kEKnWk~Uh سgϙ3gbK/577+WRi~~#L ??{#77)~{{{bl"&p̙X,>3yܜB444FFF$mщڵkӧO700`{H$m^tzCC筃X,~䉇ussn''On.]L<%0ӧO{yyu IDAT`XYYmڴI$e^1s7 @hfP 2>Sٳg/^5jԸqi4Q?FeeKaaaQQѨQƏ_QQ MHHػwoIIIyy) F 駟JKK}}},XPUU%S70EUogVZ(Gmt~3f̻wcbb7l؀-ungb?W]\\󋊊\]]ǏN111Vn9s`&{zz޺u:>>>###$$sMM80q/90i> t:NӱvZ@H$˖-Xf322¶J_۷oii)FݿV*fddN>uyՖ]`0jkk˰kb}  *..V]OĿsôD~KJ޽+))QC;K= OO+8յ]`'\X,O|LNN޾};(ʴiӖ,YzX) Y(˖- RAxx[?aÆ/_{X,H^>\~=L&NX,wUTTԽ{0l]@ ~׮]vvvҥKYYن =f===l"s qeĈ\==ٳgu;2NWf4??t_}( `JCCÜd999+V̟?_p$;wnƍQQQ}Ξ5k~э v9i$,###9ҷoߜYfihhxyyGEEaØXCƍ5kքرX+).];w޽{]]]{---OOOos>vjV+WQsdtt*`zbccbo}wfG`0)bXMMMrFwww|JcGNII uuu/^իN| .Jq/\H$IIIT*/N?zUVV4-11X!CtadggH$266wfE,cRiUU!o|#G>}[+j|D~K`0L^9;obbR\\E(dhbfB²aaaUUUիUUUVzׯߴinDDDHHB$00pϞ=jjjpBvv3SAQtСh[@SN:::[jvv6"^kkkSS?:s按 .455e2t:][[͛7**#rooo555:`0W]Q-(œ=z ŋmmm ȓY!'Aوv6~8 qI*cN8r9SllcMRSS߿/\r12 XӔBf܏G=O[@cǎ\2>>,JׅN/^x޽Xصk… 3f%%%y477{7@2kۉc9>|pBB|5kVN8 _#ć2_=ezqqqDCcƌQ#H$v.~Li'iTkhh Vk*B;;7oV_zDd߾}666 qX/SL0,#####KOO_~áhĆ㨫co`<}ܷo߇ʜ5ێۉ.{q(Qh+׮]^ÒgΜٽ{weeeUUվ}N|+6r޷oߨ(xK߾};uT>H$ѣGkjjraÆ={}W~;IIIcƌvrttܾ}{SS?}\a02m4|} 5k6e˖lmmmUgRSSS{/؇A,STIcW| :0Dr1U 7h_ݹsWKqQDQv5qUBJU%lXbK񬏺v"o{5|;Lر?8]DEa@^#GK\&o\*UmE!f}ԅ*{H}jQ>ԩ#Fc{g_|`߿Džvg%''S||| ݎNTU} 6=zl„ W^jUaaÇuuu:={fmmMLz9Fu;:Kd"H$2> ra+++A֬YsȑdKKKi+ڮ N;okA;A>}w|t钖vҥݻw=%%%--K.0uȍ~c;蓯/Hȷ^;vիW޽vڔ)S? 555555.\_9eee<O__ϯFg5~(tHLL0`633;|0b8qbjjjX٘r8mmoݻwr{$'..NJ#G<{,ԇ˙L{ꥮnaaqQءCխ:Ru M{ӧ:::l6{O0H:F 'pL5jԃRSSG7ydU@rfDTqLI4+(*24VVV`B$9ްn[וH$QQQ/_={%KްMJG+_xQWWԩS555w޵7Ph666/_}ܹs'OкBX}ϟaT*ݲe˼yb1IwUX#F_ݼy9s}kkko޼iaabcbbLMM\R[[{ SS'NH$eP {Ν߿ kD"@_>euRSSkjjJKKG]]ݾ}a)~~~SLino3'q*wK $LHH~:E/wqQ\ ,}B" BAQBPA+V@!$h$"%b RbZPAHgi{睻eX$̞99yG ~ބ)))(@ (,,477SG ޽{s۷^sz^ܿԨQ<o@ J(V%@0eʔbt G FZZ.<==}̙H~5TZZڴiHJ!$+++_(@ ˗Bʕ%]>I>]#|q|q]b4v 0$L$F򒉽Rn]@RL++ׯ+NƏJ7:"N=0S(j`@ b0L&$Dmmmw_Lfkk-Nv (MBtJMJJ8 J$*]tڵkgϞh)))GB׫\.WGG`VUU৴%BR$o޼9))i…SL5jPZI{!op@^a$ Tj)F"YGr&RSS$UWWt3v7 yF0TXb|zz۷o;::ZZZA|NSv$SܩTƍcbbЎGA+k%J...=P(ǎ#nL^Ыj[KʚD+W|ggC>X~\;WilF$^brv/S`'999III***^}>&MYfsAZII ,غukAANurrBD+xԩ /Z#ṹX蔉 :ӃDfaaannaXyyۅ\yI/%܌ɓAڧk-шRږsH.ƁT=ÀWcFFF644ttt\~K\WW𐐐;wwvvrܛ7o.ZTzLLL$.)~u1́jҥC;wtww_@@@AAAwwwqq/:ER QHwqqy&jܾ}{ĈhIH>dF9sڵzzz&(Ko #ZW^z)mKRM6ʆrH.ƁyF`b·:h=}AEEEYYyҤIOhB3?3&/B]]]EEe֬Y$ BHr͔(^SSfKJ5ĐǏXׯ_ FttީSi)ĉcǎeXǏOB(k_nkkf>|(dmIHޛ7olk4TW,I&_zѩ)bcc  ;r80 <#tQT47B=PJHP OCBhBrPKH$U>w3lB1 C;Щ^K!"I^MRpU=4G{Ub+IO6奿}D$]>G`Rn~**z& !]4SZIɼl2&IA^K!"I^MRp4Q(!(ܟZ';V^ .ѤWUKߧJ2L+r8GxWXaÆČ=zl (IGGp)i~QX7?vvvVUUUQQqtt,++C`[? > ͐f'''ahv-I*s 6LSSsƍ-W`hO Hu-`(BRDZyb)/_9rdPPի~Iyƍ#G~h4www??L~]lp8bZ[[D <}===Y,S(/cǎ}ly CAMI|FGG9rJIIiڴiQQQjڔ!\. G@lomYY ZJ<|PlSIIr~-g`{h!I1ctuuo߾M (((...SSS?$)2'0_J۷o͚5UUU^/_r^z5bĈe˖ QKKر#,, ðӧQb JݰaÆ `ll|U$6= i2 !:a bz̙3/^|Igg̙3W\9uTy e@{tA.]dkkaXjjʕ+{}7oބh[nܹ3++ &~H|||hh(a~4~4>>֭ 0$l6ٳZZZ&MJHH 100ؼy39ufmmmuuu555Q7nffG0i$--- gϾ|yss̙3?k B!,,-00CɏR(SNUVViiiٳg[XXTTTtvv&|xNNN{xbyy9Tʾ&0hDDeDDѽkkk_vM4'Od2q$//ojj?߿ @yEFFՄ=(_|HMMΝC___aooZ[[+)/3>rTcǬkkcǎ# <>:}tGq]]7|Y[[\̈޽lٲqM#jbt333---iMMMKKˬ/\rtttttP(</$$ŋ$yB]pյ… rrr5ǻ|rdddYYɜ3g1N3StL cte˖:!///_AA[|=V?buЮ |PXzq~O?T^^iiiFRhCk׮|~~ ӃWTUU7lpIUUA7))),,,22ښJ_>99iooww{5 7|gΜIRY,:ð^uCLzzzt:xduǏGDžaaazzz %77Wi'NwSǏ럵cCCí[^|H͛ $ mC [6lXJJʰa39sIMMMUUq޽'N _U 3f0Lo"no=`ѭ[xҠ ???nbbps={wuuggg/^ڸq#WIIɖ-[Y;&'';885SRRHs_ۻ ֮] UsP^^nnn8PT ׯ˰7:yq ϝ;G6e%%%}}3gX,V\\܌3у;--mڴigϞ#:uŋkjjPxOOb2L&SW]llQlll١S<OII egz###$ԩSRGRF2XI\ZOKd2R(O?p}'ި+Z 8nq P(uI( IDAT=z45jTtt4~tǏ?q(_~JQQQAAa?3~ѣFb0cƌ9|0 455vhkLMM%q666fdd,_|Ĉ CYYѣļĦ^iJXXo;@ !EEE<e0hK^^12֖ohhx%9##CKK+99011r(ѣG>~xŊ|>W!fff7olkk{ի]]]|>CBHIݺu-//OOO/..<; È9իFFFHJEd(lV^[OKv}!ZfMOOazzzOniiyժUPL\+t-qGvk @g7h755{Yt Wḻbe <w}w+++*s|L% Ҳ;++kǎ΢ӉL+W͛G0 p8uNvqqA|||t:6Y6m" 4ZF.d„ Hz}}:d2;0%e7mڴ]v999}g[[[ر7΂ :;; lJ 'I)JE1[ZZƏ_^^9 qQGG1 |ѣGݻ'Nnݺ[VVVGϧh aXNNiir}}=>:rutt z[[zQO "L&=jW^g!\.8ə$TUUU\vcc#yv*++)%H֓RbfggAR~`0ꂃ322L]@%5UJuqqYp!z R_~eԩ1N ICnF*qp>_SS#ǟBM ~;K.Dh );2 mxD\YIGKIR7ntR:~͛7b CC#F(((x__:!{NEFFz{{Kz޿_WWW|B>ۢOB$?366*̋cDzk`$$NNNȀ999{522RVVf0DCۏGkff&moosrr5k_|; WW׬}Ŋ6meܹ]RR䄄ܹ3??޼ysѢEVڱcG```VVVWWן>]]۷o?2;??b???___Mq4\%5Vz}`0֯_n:|7DCCCGGq兀CK'Z믿{.277urr"zyy8pΝ;T*444tɒ%ߪU***tuumW_t:=,,盛JvYVVc'!8[fMUUab$e|r.ի#F.[LcWW+Wzjȑ)ZIzUի;@p1L(\ϟ?/544lӧOjЊO.ʕ+nnnڊǏ?t`4jTUUp<{l ׿222z}򶶶v?>>m۶mGr֭[lzzz$=9sg^xaggP[[+VV|rQ?SaaaCCCJJJnn;KHEo"##7oӪ;v>>/m۶k:ZξUjj* > & >?߼yX߹sgqq0oߎ{XZZvwwgeeyzzFFF:;;STmmmJJJD\4Z Zb`fddtq)hffGŶ2"""TjNNΦMZ[[===aڣ0'ʼFFFuuuO]v577gff644466fgg777^RRRf͚z̙Ptj-l޼_gf'''jjjJqㆵ∧&MeaaqYS"I3gδjll|yI444 "08>˼~_PFhQ6`sϝ;7|fϞmaaQQQG>>۷oU\\ܑ#GѩSNEEEIYM1鉎===zMr;99ݻŋP)JHHP[HH]xk)Wz^ e<ׯG嵵ï]'<~ɓEG.$&&I^^ܿ?:naa!''gii)$ B/_zxx|rQs}𡯯/ȰwuuؙG9T*رcxcg{'O,\pذaJJJSLILL PSSO[[[W\\UUUݻiggf]]]kjj'O7ns.L6e%%%}}3gΐl4-)؂"rx***OdYUOVp;7n+W߫WS(:??q 6fo߾Iye˖ԣGO$@kKKKZSS.DީcǎӧOI ENN…  … $,YbkkӺG^zO>̬Ν;]]]wFV:th޽o޼y왁֭[wO>|ƍx~|V^m۶pR[4с7CqWקH2,'kU^uҎ9IPl2o< DL 444P̚HBD\RpB.\.WOO :b} N<9l0ʃ>3]@ h2 2~r:d2&NZ Ç/..633C ɼrʼyh4agnBr㱳vqqAq|||D%%) v!}*AAO aPLP͛k׮" R__ooo sss8q{͘1C̙[ojjjgS2knݺKUUU_SS_:;;;;;: Dꂐ] E{BxzzFDDh4ӧOQ(ZJ6k֬oo---xwhKKիFyft 8qbwwرcp#&'>>~߾}bwF߃])##㧟~ںukuu׊+ľy੠G49a喖۷oh999III*** fgg!'//555B5iҤΚ5שU$1%Df!P!?2R˔2.Zԩ%%%9rݻ cʔ)WTTyuww7V4(d2njsyss,_<,,͍Fq~={DDDXXXK.tqq-ѣcccgϞ*n YȠ'BaXpwu{!֭[;w0iӦ%&&"0zh BCCe[jUEEm۾+旭-N +..恁bh$1׮]+ [fMUUar YȠ'(0ۣ<)P(h2*DSIp**FIrt:0$wTBj")&I8}*ADAO =J 'bAxnU>Ch4hP$;KI.O!1h2I? G"K.HJ/ Q0`h38?* 0t?Xd0C811q˖-7NG{Hd6@/ 3g }"1|( @{3f`2 ( ,+..n骪jjjvvv̴cꮮ555x)S())9sz{mmm@@'|ڊg?uTeeeMMŋ kllhddgX<OIIdyxxUYblG_Hzzz:w7o<{~֭w~ӧOqF$~[zmjjjï^ӧUVV޹sk(UOOOxxw}WSS#UUU___%$$ ӫc0vvv...hޢ"" mii?~|yy9Ng2%%%&L@@!eMk.'''$?==}߾}999HV-Djjj̙si99˗gddD<<#xטFCCB7ֆKJJ,YB?[WWQ]]tjP(x*MMM\eee666STKJ/\d2Ϟ= Np[=&);tN@\b|zz۷o;::ZZZB_r}ݠTQQ .+@{;&MYf6rrrTTTЩ>@ٚgooကsss_h~츻>00 m?:]0xP~wOjjرcl6& (Dg,X2gϞDNNN?~YCCE.++0 EHIIqss6lѡC:::䤥999ijj*((XYY]~6%%eذahtttu{3*sYY1_&IR/Od2L&SAACڨ#?gϞ766666 c}vΜ9vvvsΝ3gN}}?ۿ曆UVyzz MCANNN3g믿***qcٳg(V- #!!ɩʕ+4 ͛7555'OD&$$,\ʕ+looocc`gg7|T/BA+ ^(𘘘E?F}}h;f *X{බߊ;vO?4uT< ###44o|~": _<@C"k IDAT زejhh?|>FC1 155F333CBB~7&k$iZֈX[[޽{ܹ@{?ܸqcfffxٳg͵,,,~'JII5kȑ#W\[aݭ7nܰ>|Y\\Bill3fP+Q__I$ō7<<gϞ߳g' AAA/_tҭ[Pŋ9rSNEDD੾CzTEE%00|藤}W^9r$==f/XܹsĘΝ?>dscccbы/F5jݻw!wOb0ZZZ-*((8jx(xX'$ed ***|||<<c?}('OE'NMJJ277;wS劊_܏ O>=>>411ill֮Euuu|I~~>IHHLLF1QWqDNc8wp  977)99yȑW^ŀwLcc#{EOU\WWP%xEVPP`0t:۷xkך Ν;&OK~W-Ztd==+WEIƌKpUPPxh|uu5͛7jhh#,KLS3gqlluIGUTTZZZknnVUUd3f(***((̘1#>>$E7n!G7Bx<4 /TIlX?*MdUVVj*MNCC_@kllkZjӃ{G@mffFðtggg@ yu34"*++5|Xt'OD'NذaCIǏ!O<ח%77vttX?\R)SH"gZ[[; 3f̓'OϞ={#H`9sիzzzxg,J JlZ N:U/׿`W5G &䈆MLLD'޻wOy̛7/!!0o2Mkttt|1V!ѴgT.1t޼y0??mٲܰaCPPPII +))ٲew_;kwΝ{)..joo^x1Ff͚'N8qbڵk/I 蘕GsrrΝ;w\;;;<‚ n޼r;;;322<<>~„ rrr#G>aؓ'O?~,~|?\NNN]]/HKKR~iP 0 fQ8 J9==}ܹhQ! #Gtww3zŋѲD3|<v AX`|Q? G? G((~l6[~~~&蕦&0~T0 #Ge 0> aҥ`= 2":$(!P(iF-P1 s C ?SWpIENDB`gWidgets/vignettes/radio.png0000644000176000001440000001430111406427017015674 0ustar ripleyusersPNG  IHDR~ pHYs᣻tIME:)TD!`IDATx{TSWsr<> "jEQrgZC83JckkR鴳ƹCZW-:v]:;耣B GKxG^ؘB@@~ug>{6?ArXPnے)SQDsDؙQ _4VWP[bA(bexغ:lI͛oC.5<<~TVV+|pvKk(DWVV<ͷp$*p!vF8whOFHdD,o>4^WzB>w#Q6G0nEcyS oGO\ne}8:zջ|0u)h;0*!G:ZD\bZC}͛7571;w믮F'h|8㯆)5mrhQ_ sB͞wz:jg/=0{:rGc=Ѿqe!MSY.eI//Z S~4FS|ZſT39˜q$T4B͋Q2@wJ!~s<^'wvK9"sr]@Us#J_$;t}G聢}eF9O_x+$IQT4'Uw5YuMrW|ɩqaҽG y WxaPɃl~ 6) "q_=le,"A;]ZѿjBLTgx~ 5\{rɕR4 &IN-Ta ΍֌m"H,ݟbw88E?yfy7/(zsMn_dh1OuAW{NMMB̓(c0iAjӄA@l3&O462vCkdJbFH]l&p[MDBii üQUaKY\Rݬ!O xaޤU|eX۸_&`XXi("{L{ǫ$Uo-q&; l<KousHGWл4_Bxٟszf0`R3N.m6ۺl8LO?9l8uP5q\OWnU@hP@WkCOgӍftFFغ:cŦΣ/66̜e꘨:΋e7Y|1͗|;+y4y|_f p9lŇ?pci/>aW#`L/m,s~2ܧ^i8)q\6pcg$O^Q$ L$ˮW[z| x9"9G(gw;8l.XHc\H\͓25h.O6;-vs_! Q #ԲKLr=j| *nv< fN;{y=EV4;d,=3gaΠ9ҳlcк}:E' 霗l3~4dt]*-@&ͥRWp%*T %ͣRI^u&dPlRNa xG0:$).~}w؟&[5@dZ'e?_B W\AIeK< fK<1d\<):+ hXL5ug'2`ˊщ#)%\.QL|>sJuVM׌[W^K6&Qd2].WeQNO/> K/b$ ]g<1[ !yչ7)߽p9r wXaћ ?U|?c(`rL6 C5%\篰ʛI 4 ,h`c q??2YplRjX"겁}v J2f%>&IQ`2{'NcYѥczqX h\obk,2;hʢֲ?9QGlUЕl!mvb W*D3i VpR f_X{t>)9?$7Mdi7ws%e{rD n4ɤ *ZڔJM/-URC$!)I|C$/2Vm蔤˧:hc+G2I%Gw)c6'ڌ]~} "MXPggc2F+5\,/|Wb”$͗>0ΓDX25{mgK6:- W/8GM Q\PUc}O* HI`Wp$b4J)瞼>F=2[/)A``[ w#ACP8AACP8AAP8CP8AAP8CAAP8CAAP8CACP8CACP8AACƴp:NFGG+hVɐpdeeiTN٩RSSZmVV(D"V%>С|mp\.nܸ񒓓oܸ\.733377wķ<~ܹsJell}ϼ{S*{bA RSSݯWXqiz+VSSS FvSNofMM;}lrر28p`˖-۷o裏b5ᚚrK%>С|mp\.g.|syN-KTTb̝;zSNU({~J~gST~~~}n'ŹK޽o,WPP:HԂiiif}駟|Zزekkk?89997njnnќ;wKmݺo,$)#˛k4'N۶mێ;\.?~|A7o/=ӧNX,;vXr%\rǎz~Μ9C zꜜ곀jYzϫ&Mڱc^?>,X@%''{REEEQQQktttQQw)쿱 FIIIIOOL=F3PĴ 6,[((jٲe7n\p'ϪUxbV\\K/ݳʺu.^)7׫jFg4{{{Fc^^FQׯ$O?MҥK=)˖-p8+%KY_TTZvڵ/g]~_X" @վk;1mt{),,4Lr|˗/OHHVCFkeapXf ]NIENDB`gWidgets/vignettes/helloWorld.eps0000644000176000001440000005671011406427017016726 0ustar ripleyusers%!PS-Adobe-3.0 EPSF-3.0 %%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner %%Title: helloWorld.eps %%CreationDate: Mon Feb 12 13:38:19 2007 %%DocumentData: Clean7Bit %%LanguageLevel: 2 %%Pages: 1 %%BoundingBox: 14 14 171 87 %%EndComments %%BeginProlog % Use own dictionary to avoid conflicts 10 dict begin %%EndProlog %%Page: 1 1 % Translate for offset 14.173228346456694 14.173228346456694 translate % Translate to begin of first scanline 0 72.566014916347513 translate 155.988362772936 -72.566014916347513 scale % Image geometry 273 127 8 % Transformation matrix [ 273 0 0 127 0 0 ] % Strings to hold RGB-samples per scanline /rstr 273 string def /gstr 273 string def /bstr 273 string def {currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} {currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} {currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} true 3 %%BeginData: 22976 ASCII Bytes colorimage rr@TmJKXS-rr@Q~> rr@U?JOf?&rr@Q~> rr@UfJSt*trr@Q~> !<=6nAq=RdAcX"SJ,~> !<>W@Uk,?6U]EscJ,~> !<@"gidp+]iW3osJ,~> !?c!*8:a>(8-(OiJ,~> !Crr:P(AegOo]SnJ,~> !H-nJh1=DSh#X`tJ,~> !?c!*6\.Vs6NK"dJ,~> !Crr:Mh-fYMZIigJ,~> !H-nJe:H-Ae,cdkJ,~> !?c!*51Dar2!?Un2#]Z=2!?Un2#9B92!?Un2#KN<1a%;~> !Crr:K[bYTFm*Q?FoI$oFm*Q?Fo$akFm*Q?Fo6mnE^tW~> !H-nJbLF]8[HOCd[Jn>L[HOCd[JJ&H[HOCd[J\2KY\ns~> !?c!*3Rp+j1be,t">DYm1be,t!AHA.3<:rjkZ\'A2#TE81a%;~> !Crr:IarlJF_^-)"DW(.F_^-)!GZcTIK=S+k`c*_Fo?aiE^tW~> !H-nJ_puX*[A<$2"JiHC[A<$2!Mm.$_Z@0@kfj.([JduDY\ns~> !?c!*3Rp+i0]lR@0KCiL>6$AT3<1bq>6$AU3<:rZJ,~> !Crr:IarlIC?C`^C49p[PQ5IrIK4-FPQ5IsIK=IZJ,~> !H-nJ_puX)Uuoo'Ur0"jblFR;_Z6LpblFR<_Z?uZJ,~> !?c!*3Rp+i0]lR@0KCiL>6$AT3<1bq>6$AU3<:rZJ,~> !Crr:J(9#KCZ^l`CO^-^PlPUtIfO9HPlPUuIfXR[J,~> !H-nJ`7;d+V<6&)V8T4mc2a^=_uQXrc2a^>_u[)[J,~> !?c!*3Rp+i0]lR@0KCiL>6$AT3<1bq>6$AU3<:rZJ,~> !Crr:J(9#KCZ^l`CO^-^PlPUtIfO9HPlPUuIfXR[J,~> !H-nJ`RVp-VWQ2+VT#FpcN'j?`;ldtcN'j@` !?c!*3n67k0]lUA0KLoM>Q?JU3WLkr>Q?JV3WV&[J,~> !Crr:JCT/MD!%#bCk-?aQ2kb!J,jEJQ2kb"J,s[\J,~> !H-nJ`mr'/Vrl>-VoGXsciC!A`W2q!ciC!B`W<;]J,~> !?c"K3Wq0CChP[$3W_3@/V,tO3WLns>QQW@1$2^@1&O'41$2^@1&X-61a%;~> !Crs[J-8bWDJESTJ-'Rl9S%`_J,jEJQ3(lQD!%#`D#Ae`D!%#`D#JkbE^tW~> !H-ok`rpKlDek@.`r`,ECOsOp`rN(#d/p8eW92J-W;O[9W92J-W;Xa;Y\ns~> !?c"K3X%K>]teSEq`4g=C/6^<3q#*01$2^B0fh&O>Q?MV3WLns>Q?MW3WV&[J,~> !Crs[JH^C*]te`/qgeipF'*R9Ja\-iD<@/dD1QQdQN1n#JH0QLQN1n$JH9d]J,~> !H-oka9B:l]teilqoAlOHt'L7aR@1MWTMV1WQ;($dK$9Ea8i4%dK$9Fa8rM_J,~> !?c"J3X%BJS=<23rAk$B9PQ643X8gfZT:-Ms0Kg.!a5Q0pc8INs1IMU!& !CrsZJH^"'S=7JUs*dcH1V=Q2f/)JHCi2eE;A_D<@/dD1QR#Qh:=SQN1n# JH0Q`QiI*\QiI*^QN1n$JH9d]J,~> !H-ojaT\e[S==$&rQ,/_GAs,)aTp5nlH./qs6@_J!n%&5prNT_s6]!k!3,,/!ia;@qU5$9qU,AC r5er !?c"I3s75tZY4'MZc1!2Q[>5tZYq)\[Qs0aWF3rh"t >ll`B1&>2Jrr>=]>lZVW3rh#3?2jm#?2jj(5l4ge1&X071a%;~> !CrsYJd#OpHZi; !H-oiap!i=HZj2HrlP:sGCT/*!m^i@qoSufs7Ps*#h&b%V976de"t40"4I4uV>879ci;XmkfNn* k0jC3b,YqU>HDqU>HD!0I*,!36"?!O-Hl~> !?c"H3sd]F>#R7>4#_%3n2g_Es5GU-3s/I^fIc\V$!RA10KND;X=u]Y3s8aeX=u^33s8:X[P']+ 3rh%u>llcC1AY8Vs7S\Ys$6He!&FI6!&F@Urr;n%rr !CrsXK*kLY>#S[YK5>I!Jan?pNW83Nr.>*8s5@GYK*dkD^M/1`s1`8tbC]q`s1`8tqL\p3s2Sc% l%8tRk*Q3fK5UOQ!<;b+!WQj1QiM%%K)ffbR/[-`R/[-cB`".sDZ,1gE^tW~> !H-ohb6i5k>#U-ubFrlcaRRFUci !?c"H3sdr+77BO#3*SR+n2gbFs5GRirAt-]s4An`oK*@_s/[n8>5tZX3m0Sf>5tZX3r1o@:&hXT 3pA^+1?MjD1-78f>ljsjpK[h"5l4ge1Aj361AG/Ss8H='s8P@\>lZYY3rq/\J,~> !CrsXK*d#s77BUVG[X6ln:Lk's6*j>rIY6:s5@C8oRdI9s1`8tQN+^6J'3HIQN+^6J,4d#O8m75 J*DRcDs!GhDhE!)R0!>$pR)'^B`"1tDu>4fDtob"s8JGcs8Qd/R/h1(K)p!_J,~> !H-ohb6c-g77B\5\S,'YnB1s\s6l8krQ>>ls6>uhoZIQis3m^^e,Rmk`llO.e,Rmk`qmj]d/Vak `TbPGXQJ%7XNR^AeH,]3pXK !?c"G49mf-6q&h!:,D?$"AAdS/33Yk"B>ER/NNem#&_HMqWFqRr]Ccss/[n8>Q:cY3]oQ]f(\pi L\Nt58,^I,49J^cs'G[e$c)a74?Pc_f(\piL]'=PBE+lIc1M$*>Q:cY3]oWpjne)-;?+'X3pAa, 1?MmE1-@>g?31'kpKdn#5l4jf1Aj671A>,Srr?C)s8P@[?2ubZ4978]J,~> !CrsWKElZe6q'CB;JklU"HNNG@"/'-"I&lE@=J3/#,L#Ir:%mire(lMs1`8tQiFg7ItWK^jnei8 ZhT1TMuMK1KEIP?s-`k>!n[I4re(H^jnei8Zi,OoTE!!-ht[5/QiFg7ItWQkn,2XhOoNI7J*DUd Ds!GhDhN'*R0!>$pR)'^B`"1tDu>7gDtf\!rrAJds8Qd.R/h1(KE6*`J,~> !H-ogbQkOH6q'sd=/YN2"OR2;QG`[F"Od>8R)K!J#2/MCrqYg*rlbu(s3m^^eGn!l`luZbo_na\ i:tLtci3G5bQH>os4.+m!q609rlbQ(o_na\i;Lk:fDk'fo)/O6eGn!l`lu]gq#:'MdJqjl`p(\I Xle19Xj!pDecGf4pXTBFOSdT/Xo-BCXnUEGrrCXLs8S2Vec;iNbQ4qcJ,~> !?c"F49[N.2D8,`mQ:VFs5GRirB)?)s4An`4?Sf+j/ABXrT6d94Bqie0KNGQb>!WPFZ?31'kqd'7Xr&as7p0R[ss$6?c!&FL8!AkpL~> !CrsVKEYmR4[E.PmXt_'s6*j>rIcG[s5@C8KS6r:m(]gKrU#MrKU;_RBn)KL^M/1NcN!@F\F'=9 pk0LGp1]25[f?B%I>!:IjBR7hcN!@F\F'=9re),\s4.&-_9ZVWs1`8tK[g%d[CPhXs2Sc%l%B%U k*c?jKQ-dV!WQj-RK !H-ofblsD#79!?Cm`bm^s6l8krQPi$s6>uic->;Kp=IIBrq698'%R$2U;tgae"Xn-li6_.ch%1q prsZJq4Z'XiW&qm_p-I'mZ,B5li6_.ch%1qrll;4s5O"If\_qAs3m^_c0bQ%cHl4Is4F!al-042 k19[;c*$op!WS8Uf)bo5qpthNr655Ep=K6Bs,d$-!3Z:F!O-Hl~> !?c"F49[]1-rjP0mQ:VFs7Nb/rOF5ks4An`4C\8q/M&P0CAt7q4Bqie0KNGj^Z4MBq9]eV]Ys._,*F8siL.kj-@s(XYYBE/!j.P3;+=9#?U3d(JI0.\eEl2S1F3pAa, 1Zi!F1H[Ji?31'kpKdn#5l4jf1]0?81\G)Rs8P@Y?2ue[4978]J,~> !CrsVK`tUG5#klnmY(e)s7aO\rR3(Gs5@C9Kq84c?=.D^OoE.HKp_nTBn2TN^M/4ss5RTrBl`;7 Pkg"i`rCU>L">_Ub\i*(s0uKdW;kmf?YOQAs-/4kT`>%l>[_;WOoN11J>iM&?XRVnmf1=?J*DXe E9 !H-ofc38P^;cR+Vm`ks`s8(I7rU)!$s6>uicIi0VO-HB:\c:4$cIW$EU;tjbe"Xn,Es1ck)g&M)nOI)Z4aoBhaa5$^ZOd2fGo`*R:`p(bK Y3+=;Y0O3Hf)bo5pX]HGOSdW0Y5HQFY4^EGs8S2Tf)VuPc2k.eJ,~> !?c"G49mi6/ic^&7Q9cu!)*(d,hO\/4L>&\5"J798D`Yd4Bqie0KNGaMErWO+4D4]N.PWqD3*H9_0KQoI=tM`p3/[aE008>[!&NbD !])qpqHa4&5keRcs$6Hf!&OO8!&O=Tr;ZIs!&OR9!AkpL~> !CrsWKa2B^9M&#T88msN!0?mS,iN0]L!]jBEefC)L$8#?KUDeSBn2TN^M/5Ls+b$1I=.^f`cq95 />rNIG(fM-^[u/j]`4"+Ib+OS@=3KNT`<#UKqSJ->AS_9H^"KEBn4e7J7AM*"L.pHB7K0"!-..j !c`p6qO7NcB_Rtss(M;!!-.pj!-._%r;ZJ[!-.sk!HL\\~> !H-ogcNg%1C048,8uV4)!7U]B,jLc8cg:\*VT6`s_t*Gpc.E!EU;tmce"XnOs/hX&_8+@rfXL_' 1u82M[a4j*eG,ZYjSuK\`:*`.QbUAPcMuP+ceAEdNi9e1^ !?c"H4UF/81HRKY6UO$tn3$hHs5No*#"ARE/NGuOq>V<2/NR,9X=u_?s/[n9j8CYh3^#Vos5#Fl q`Qc*r5LKus*8ef`2s/[n9iqY/`3^#W4s0aRBkrf#& k$J0G4YuqA!WPFZ?NL0lqd0=Zr&k$9pL!q"!'pP`pKmnVrB10<+Fj~> !CrsXL'2ck6@a(T6NKZ(n:h"*s60>a#&sV$@=O$tq>V<2?\"RE^M/4ds1`8umJ^L8It`W7s5msH qh?qdrR5VOs-]>UI=U)OAo`Iira9htKnbKbk%B=?s1_ujJqf#Js1`8umJC13J;/fIs2Sc&l%T1X k*lElL2m'Z!WQj-RfWP&qjRS*r.Y2kpRD0^!,2B3pR;/&rIt>n7t:~> !H-ohcj@6V;T>h16UOYanB_6ds6oiF#+Y_YR)IAGq#;.pa4L@?U<(sde"XqYrfOS,cd:&=m\%f$ cns2MiMkE.]"n?E`UWqnZH;n@OgN*Rd*Vg\TZl-ie!@kmd*UDEe"XqYr/\>+d*UADfV$:LciC<4 f`JD)Ykm#Rs,d!.!WS8Yf`88SciC !?c"I4UO;@5rCeg2F^G?6h!5@9`O*'r&G![s4An`4mi(@@h:.O>Q:cY4'V`d0K\^q.QBNh4TkQH /NW_k'@Z\3OT.U8s,8r0eg`XAme&%h48qAKqWf^oB`F\Y3rV8R>Q:cY47;Me3'9>e;ZF0Y46\m. 1Zi$G1HdPj?NL0lpKmt$5l4mg1]0B91\b>Vs8P=a?iL*#?N;n\4TRA^J,~> !CrsYLC8`77s'NACI_,u=GH@$"-EQH@/PEXNW7sGIu![nq1fMdI[^;OBn2ZP^M/5jpfi-!reCUQ n6ghDLD/\CBXn(ZIK-0ipu,G(K_5%DI"_KS#lF+!JYE+OBn$&:&=WX6Bn5jH>^_<]LQqhZB7T6% !-74l!cj':qO@TdB_S"ts(M;"!-8!m!-7k)rr<"3!1a&gpm_>)rJ(Do7t:~> !H-oid0n-.9sW0oTL_gVCsVY!"4dG?QMeT)b5^ao`R4S\q5b-f_q>"_QrQtYMDL_~> !?c"I4T\,]1As?=4)AnU61I)@9`O*'3W2)H34Tn4R hCCV_4VFLh?c(eP38VP[s.:l'4lcJq3W;/J7K;3p3GAGb0g#@t#[@>10K\:i/NNen"CM2;00AD] !&WhF!]3%sqHj:'5keUds$6Hg!&XU:!&XLYrr !CrsYLB;$rAGq8d?u0h%B(:WZOT4NPJ,P-.QN,oPIu!FkD#&/gI[^;OBn2ZP^M/5draC50LPLig k$EQ6LEFM8K\,NoH0N_:s0c?aL@5%LI>3N4N;r$HJ"cnMC4Q;=&=WX6Bn5UJ?[d`bLReCbB7T6% !-74l!cj':qO@TdB_S"ts(M;"!-8!m!-7n*rr<"3rg`ufq4%G*rJ(Do7t:~> !H-oidK5)3Qi5>8KktaJMt,3uf)P3)`;S*if`16(`R=P]Rea<+_V+t^%C3qs36nIdJ3^)_U6f[eGns#`8(C:V9/_b#hf7,U<33.PJdCJ"PWn.TZHBG !4(bA!j^7[qV)&NOS@K1s,d-4!4)ON!4)FTrr<"[rnIGPq:bnTrR(_NDL_~> !?c"J4p"#p3;YlB<0<2j4n:c>:&j3(3rM5K/k%Qn"rX=u_@s/[n9^Ah\&r]UI/ s0aL?qE>O3s-N;X/30g)Q2bPQ3^1:X@lXHO$$ZEX/NRSFT.rG,4pYEnX=u`Ms&qJ_4p6rH[P'`, 4odG9@.aKq?ii/K2#:S\s$6$hs8$+'2#TT=1a%;~> !CrsZL]_U@>)3'4"bp`RNdu0@L]ik?k[8o=L^BFJiF.4le,Q1iqLB'/RfC-:JXc\SBn=n9LOB)W "KVRC@".s.&ubi6p;10bbP/:AMe[`tfDgVRreLl]s2SMrUAqW9K)UQ3S,^6;J_0pPIf>-+])Tf` JE_jiF8DI"s8&8fF,4o6SH8b(pRM?bB`">#F8UgoF8DI,s8Qd1Sc8ZcSH*a0L]MNdJ,~> !H-ojdfZ7fIFA)C"jh^\Ne")!dfe8%n!:ojdg=_-lBoQ>n,L2;qT'/mgAfWrakHdDU<2p)Xht(d "Q9=4QGiXK'&W`1qUq+MlMAd*YGK4enGfW-rmM23s4EXUh>b]qb5TiqgAfWramf>/_uA*fjo !?c"J4p#n!4o7DH4+aZ1HTUg_"ASpU/3<_n$!.)Y/NH"+rUO4l4rI1=5!E6OX=u_@s/[n9G5p&V 5!DQos(*iDqE>uiqX+<(004I[mJSq"4$Iife3?,\8_sDX00*_GT.rG,4qM!!X=u_[s3!Ge5#CSF [P'`,4odG9@.aI!5l4pj1d3bm@.aI!5l4ph2#KN;2#:V[s8P@\@/p6,5l4ph2#TT=1a%;~> !Crs[L]`!M>_N!1"b)B5U4I^`L]ik?k[8o=L^KLKiF.4lT`4VCL]3)IPH'FpS,^6;JXc\SBn<>b hKt$6O6Zb%B7Kc6+,p-fs-.2GXoIqiA93?YX8h%'LPV#Vs+tB !H-okdf[.0E6S4."iHS.U5-JSdfe8%n!:ojdgFe.lBoQ>h#@)]dJhT4fAG'+gAfWrakHdDU<2?n kd]'iebB*GTZ$]U+4^>_s0n]@iW&TMPdAN]i;`#NdaQb@s/hs4h>b]qb5Tj$gAfWral*3[\^T$Z qZ#3@aQ_.RZhiJLrrA/Xg]Fh2ZhiJLrrA/Xg]4\Ydf?`Nh#IESOS[c4rrA/Xg]4\ZdfH[jJ,~> !?c"K4p!f53;>Z>?<0o_o0*:Os5GRjrB;T0s4An`5!Fo'r5,5.bl"e,5$\,h0KWP>X=u_"Z2`sc X6KYb.Q'<`4s&)Ns#`,"9E"n=.l][U5-b.MWN5:`X"#tgB`F\Z48qDT>lUlZ4$L1ShP@7@ci:F, 46\p/2#1PO5l4pj1d3bl@.Z_]?iW%]4odG8@/iLe@/iLh?iW%^4omJ_J,~> !Crs[M#qU^ftl2q2$0Os8QeQJs$'4h-55\M2B=RmE*TCs1hi[JYW7QC4lMB&=id8Bn;,cs6%DGp#5qk B7]<(!-J%.oP",n!d'9@q4@4lqjme0r.tDqq4@V"pn%M!qjme0rJ:Pq7t:~> !H-oke,keW]_U%[Z]KupOn7'*fDk<*`;S15g&L?)`RNDdrr)0Km.C;D^sq-=e"Xt=s3m^aeDUAu l0S9HerI,Yq:$JVs8SIjak-Olk`3F(eC !?c"-4p4U[i[d.h4ssD2fI]*I5!3/\lMU>.Ue`^->lUlZ4'_fe0KVH\K%0PheUK)&3Bd1%$_[OS .QBOSf`.Hn3W;2Q4G))WpXOaD00)1/s.;#-r]Ulus/[n95!G1jqrjkHs0aRBkro))k$S6J4uMJ1 !&a[ !Crs=M$0"Ak[8o=M'n\jiF.4mM1gf.n,<%C]m+:GSH$?7QS*lS*= >C)![k5V_rIY`i;Jtq2uq;IoMBRPW1s0ZToreV2Vs1`9!M1r.ur9qCBs2Sc'l%oC^k+2WrM0.mO !-J-q!-I@p!-J0r!HL\\~> !H-oMeHFP)n!:ojeL0)NlBoQ@e]t\Xo`"aWetT"fh#Gitb2!$GU<;$/`9@*rm_=dU_U/,/*pN^k NkN`go`*(%_UR,db/EN@r9h=[Tu,15s3.=_rm_S8s3m^be]Z/*rV#!?s4F!dl.#dAk2$0Ie[=Pr !4DaT!4CtG!4DdU!O-Hl~> !?c",56F"t/3<\n"$7ta3rV>b3\rE?.P!&(2EO,a.PNqK3[ugF5+Fj~> !Crs[:cOGCk^%>A8\HIp6W=MMcat@9d&GDgd63M@+'%@=[_Q!Jr5G5>AAfhM@Y2@BnD5"H#$bk?YO^gB7]<)!-RFr!d0BCk+;Wrr/(Js k+;WrrJCVr7t:~> !H-oLecX0WQGi^P"3HRj`W"F0`il"uO-#^&]#rUCNhX\I`K$\8f%.R7R?3MsXhr6TedA14Qbq;( e.ZNhstuedo`[U<;'<]qq!TPbPaLTZQHL!4M%I!k-[gk2-0Ir71kV k2-0IrRM"RDL_~> !?c",56F)+3BI(&"$SP%3rM8C4T7>?3=Il/5!M1f3BKGg2*!bt56o2]rBCBI2*!bt563f'r]('B2*!b_56*S'@0/;N2fZ=2o`?1a%;~> !CrsQ6M2R.2I=dB4FFAb!Mi*%1H[U%QW",CuHK)UZ6IsHEiI=cQhJa&'mFlo:tFc1D)T)a$3MZ@n^ T)a$4MZIigJ,~> !H-oLf)sO-_SuH)"4FKl`r4KkcbI30rk]&be(rm_n!Y'rmq7] ^V\1lf*9:.^;7Y(ci2Muca:R5rRV/!ZGOc`f*K=-^r!t1ZbjiKf)W;Bhu^C>\)uTK\,=hX\)uTK \,FnZY\ns~> !?c!*5Lhsu2 !Crr:Mq*^cG35G!G)LP+TE'05MZ@q_TE'06MZIigJ,~> !H-nJf[\US\E;`O\Ce=Ri;gCcfDrGDi;gCdfE&3oJ,~> !?c!*5h/+"2 !Crr:N7EjeG35G!G)UV,TE'05Mu\%`TE'06MudrhJ,~> !H-nJg""aU\E;`O\CnCSi;gCcf`8PEi;gCdf`A !?c!*5h/+#4>uD4"?&A-4>uD4!B*(<5QNu*k[FQN4T.MG1a%;~> !Crr:N7EjfKQlXR"F#NXKQlXR!I'4pMueTUkb/$$K`-i1E^tW~> !H-nJg==mXc+3&t"M)e2c+3&t!P-JQg&]I/ki)WRc2H>sY\ns~> !?c!*5h&%!4Qn['4T7SG4Qn['4Sh;C4Qn['4T%GF1a%;~> !Crr:NRWpfK]mU[K`6r2K]mU[K_gZ.K]mU[K`$f1E^tW~> !H-nJgXOsXc02\ !?c!*5_22m5QN\aJ,~> !Crr:NId)]N<+&iJ,~> !H-nJgO\,OgB"NrJ,~> "!D2A6%M+K48:o;5liebJ,~> "%T/INe)b4JbXfrNWF/jJ,~> ")d,Rgk!OtaS "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A43I$l!<2He!;Z*`!!;Th!8d2E!;u "%T/IJ]dH]!<2He!;Z*`!!;Th!8d2E!;u ")d,RaNEuO!<2He!;Z*`!!;Th!8d2E!;u "!D2A43I$l!<2He!;Z*`!!;Th!8d2E!;u "%T/IJ]dH]!<2He!;Z*`!!;Th!8d2E!;u ")d,RaNEuO!<2He!;Z*`!!;Th!8d2E!;u "!D2A43I$l!<2He!<;Nd!<;Nf!!M`j!:TCT!;l6b!<;Nf!<;Nf!<;Nd!<;Nf!!)Kd!<;Nf!!;Th !;Q$_!!;Th!<2Hc!<;Nf!<;Nf!<;Nf!;l6`!<;Nf!!DZi!:TjdqsXObrpTjes6omds6osfs6osf s6osfs6osfamT "%T/IJ]dH]!<2He!<;Nd!<;Nf!!M`j!:TCT!;l6b!<;Nf!<;Nf!<;Nd!<;Nf!!)Kd!<;Nf!!;Th !;Q$_!!;Th!<2Hc!<;Nf!<;Nf!<;Nf!;l6`!<;Nf!!DZi!:TjdqsXObrpTjes6omds6osfs6osf s6osfs6osfamT=_NcIX?~> ")d,RaNEuO!<2He!<;Nd!<;Nf!!M`j!:TCT!;l6b!<;Nf!<;Nf!<;Nd!<;Nf!!)Kd!<;Nf!!;Th !;Q$_!!;Th!<2Hc!<;Nf!<;Nf!<;Nf!;l6`!<;Nf!!DZi!:TjdqsXObrpTjes6omds6osfs6osf s6osfs6osfamT>Qgot[H~> "!D2A43I$l!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)rcrrE)frrE)frr<;m!!)KV!!)Ka!!DZi !:Tmeq!\1^'^l#%mf3@Vmf3@V!!)KV!!)KV!!)rcrrE)frr<&fq>gQarrDucrrE&err "%T/IJ]dH]!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)rcrrE)frrE)frr<;m!!)KV!!)Ka!!DZi !:Tmeq!\1^'^l#%mf3@Vmf3@V!!)KV!!)KV!!)rcrrE)frr<&fq>gQarrDucrrE&err ")d,RaNEuO!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)rcrrE)frrE)frr<;m!!)KV!!)Ka!!DZi !:Tmeq!\1^'^l#%mf3@Vmf3@V!!)KV!!)KV!!)rcrrE)frr<&fq>gQarrDucrrE&err "%T/IJ]dHX!#+f$!:T@V!:Kmfmf3@V!!)KV!!)obrr ")d,RaNEuJ!#+f$!:T@V!:Kmfmf3@V!!)KV!!)obrr "!D2A43I$l!<2He!!)Kb!"A;r!:Kmfmf3@Vmf3@bn,EA!mf3@V!!)KV!!)KV!!)Hf!<2He!!_ll !:T@V!;Q$_!<;Nf!"eT!!:T@V!:T@V!:Kmfmf3@an,*.emf3@en,!+^n,EA"mf3@Vmf3@Vmf3@V !!)KV!!)udrrC+."$8e*+Fj~> "%T/IJ]dH]!<2He!!)Kb!"A;r!:Kmfmf3@Vmf3@bn,EA!mf3@V!!)KV!!)KV!!)Hf!<2He!!_ll !:T@V!;Q$_!<;Nf!"eT!!:T@V!:T@V!:Kmfmf3@an,*.emf3@en,!+^n,EA"mf3@Vmf3@Vmf3@V !!)KV!!)udrrC+."+cJQ7t:~> ")d,RaNEuO!<2He!!)Kb!"A;r!:Kmfmf3@Vmf3@bn,EA!mf3@V!!)KV!!)KV!!)Hf!<2He!!_ll !:T@V!;Q$_!<;Nf!"eT!!:T@V!:T@V!:Kmfmf3@an,*.emf3@en,!+^n,EA"mf3@Vmf3@Vmf3@V !!)KV!!)udrrC+."3B9%DL_~> "!D2A43I$l!<2He!!;Th!;u "%T/IJ]dH]!<2He!!;Th!;u ")d,RaNEuO!<2He!!;Th!;u "!D2A43I$l!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)larrE)frrE&errE)frr<,h!!*#err "%T/IJ]dH]!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)larrE)frrE&errE)frr<,h!!*#err ")d,RaNEuO!<2He!#+f$!:T@V!:Kmfmf3@V!!)KV!!)larrE)frrE&errE)frr<,h!!*#err "!D2A43I$l!<2He!<;Nd!<;Nf!!M`j!:TCT!;Z*`!<;Nf!<)Bb!<;Nf!<2He!<;Nf!!_ll!:T@V !;u "%T/IJ]dH]!<2He!<;Nd!<;Nf!!M`j!:TCT!;Z*`!<;Nf!<)Bb!<;Nf!<2He!<;Nf!!_ll!:T@V !;u ")d,RaNEuO!<2He!<;Nd!<;Nf!!M`j!:TCT!;Z*`!<;Nf!<)Bb!<;Nf!<2He!<;Nf!!_ll!:T@V !;u "!D2A4,<8)!6+C,!3kno4$b\GJ,~> "%T/IJVW[o!6+C,!3knoJW=b@J,~> ")d,RaG93a!6+C,!3knoaP=";J,~> "!D2A4,E>*!6+F,!3kno4$b\GJ,~> "%T/IJV`ap!6+F,!3knoJW=b@J,~> ")d,RaGB9b!6+F,!3knoaP=";J,~> "!D2A4+ZkEn,EBkmfPX;1a%;~> "%T/IJV!:6n,EBkmfS-$E^tW~> ")d,RaFWg(n,EBkmfUYdY\ns~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4.kuTs.8Z]4$b\GJ,~> "%T/IJY2DEs.8Z]JW=b@J,~> ")d,RaIhq7s.8Z]aP=";J,~> "!D2A4.kuUrrA+OmfPX;1a%;~> "%T/IJY2DFrrA+OmfS-$E^tW~> ")d,RaIhq8rrA+OmfUYdY\ns~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As6f@S!!;Th!8HuBO.PeB4$b\GJ,~> "%T/IJY2E2s6f@S!!;Th!8HuBO.PeBJW=b@J,~> ")d,RaIhr$s6f@S!!;Th!8HuBO.PeBaP=";J,~> "!D2A4.l!As6oFV!<;Nd!8HuBO.PeB4$b\GJ,~> "%T/IJY2E2s6oFV!<;Nd!8HuBO.PeBJW=b@J,~> ")d,RaIhr$s6oFV!<;Nd!8HuBO.PeBaP=";J,~> "!D2A4.l!As7#LW!;u "%T/IJY2E2s7#LW!;u ")d,RaIhr$s7#LW!;u "!D2A4.l!As7#LW!;u "%T/IJY2E2s7#LW!;u ")d,RaIhr$s7#LW!;u "!D2A4.l!As7#LW!;u "%T/IJY2E2s7#LW!;u ")d,RaIhr$s7#LW!;u "!D2A4.l!As7#LW!;u "%T/IJY2E2s7#LW!;u ")d,RaIhr$s7#LW!;u "!D2A4.l!As7#LW!;u "%T/IJY2E2s7#LW!;u ")d,RaIhr$s7#LW!;u "!D2A4.l!As6oFV!<;Nd!#4l%!:T@V!:Kmfn*^5Vmf3@Vmf3@Wn,JH?mfPX;1a%;~> "%T/IJY2E2s6oFV!<;Nd!#4l%!:T@V!:Kmfn*^5Vmf3@Vmf3@Wn,JH?mfS-$E^tW~> ")d,RaIhr$s6oFV!<;Nd!#4l%!:T@V!:Kmfn*^5Vmf3@Vmf3@Wn,JH?mfUYdY\ns~> "!D2A4.l!As6f@S!!M`j!:TCT!<2Hc!<2Hc!:TCVO.PeB4$b\GJ,~> "%T/IJY2E2s6f@S!!M`j!:TCT!<2Hc!<2Hc!:TCVO.PeBJW=b@J,~> ")d,RaIhr$s6f@S!!M`j!:TCT!<2Hc!<2Hc!:TCVO.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As2"1(O.PeB4$b\GJ,~> "%T/IJY2E2s2"1(O.PeBJW=b@J,~> ")d,RaIhr$s2"1(O.PeBaP=";J,~> "!D2A4.l!As1aVdmfPX;1a%;~> "%T/IJY2E2s1aVdmfS-$E^tW~> ")d,RaIhr$s1aVdmfUYdY\ns~> "!D2A4.ksAs1XPcmfPX;1a%;~> "%T/IJY2B2s1XPcmfS-$E^tW~> ")d,RaIho$s1XPcmfUYdY\ns~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A4+ZjOn+c>R4$b\GJ,~> "%T/IJV!9@n+c>RJW=b@J,~> ")d,RaFWf2n+c>RaP=";J,~> "!D2A6%M+K48:o;5liebJ,~> "%T/INe)b4JbXfrNWF/jJ,~> ")d,Rgk!OtaS !?c!*6%M>o5liebJ,~> !Crr:Ne*5_NWF/jJ,~> !H-nJgk"8Qg]=WsJ,~> !?c!*1k@LT1]SYK~> !Crr:Ee/9&EWAU[~> !H-nJY^s%MYQ/Qk~> !!%QmJKXM+!!%N~> !!%R?JOf9$!!%N~> !!%RfJSt$r!!%N~> %%EndData showpage %%Trailer end %%EOF gWidgets/vignettes/doPlot.png0000644000176000001440000012403511406427017016045 0ustar ripleyusersPNG  IHDR mkT pHYs᣻tIME y IDATxwTW7.ޛt"Aŀ% ##,@{7&&6@ETPbW:"K6,, 6q͛73-w޼B!mo𕼹"IX#a|yv6vT5kyz4 !g"o^ @oP\$bҽ5^HL^1~!DͭA^v-uAÏktonD@aÐHnd +---Y`qJ_(}(/gL@K0 ͭut&OrLzEV]ֆjbc48B#\)A-}DOֺl)'Fn?Du_RTO \rMxii9x' K3һR4(dNyX&&!{ȵ[PП`>ŲxDono^"`|ȩrCU F έ%9 3xdEԺETGTGk畇2jDjkD g^ғ?"ӤT1UҳVkYK0Qrn[kvMZ#DQz-""")ͺL7j(0˽Y~pIcLO#(k>w7Ҩ Ş5XUEe(`cؽP?|s%Xg%eTmo"7u ,g7hkmI3i {0zA~f2X:)9 ke,[_LTC` ,aiКZZ2 GH80$&M4ե+E$X$QCݐbŌՖSg**uE{9OدDwxN2N#/N-e%f#]]Jòxj{iy2!1SQSVü ϩ sm F4#UI{YXq$UVFdBG{~k:r\sKɛ/S'sײVty(d O ƊFPSN!Y 2jLM㣉9+<8r8v&T7ˋvb?t$ T&6Y=;yQb%rv xxKcMKc-Yږ ir|cU)+<]BM9RK:j;ae"|k洿ǓN]U߿[!:j%]އms:d.!A5"H=.BD+H0E($2\~=I*RUÇPЩҲ%nKEOSiO(xOD&)Ɨ LְeZ[KK!Ywԍl-J{~f"֊Hm[yबӚ~aM*)4|*,&&$e5@V]ni2eݿGe:#QBM~1B!C0SHD&KЩt9 {_5r?tA-&3zsҲ1Ս2U$(dE~FF5"LRR<#(Bm+-#J/A6M4{xaB}Qǝ-"c"%a;t)"+E@kܶ{g 1W$6b/-Ⱥs6껟}8moWBMJ׶Wr^7o#п%=+QW{-w杮r2u}v򫚷2*暴BQTʐgj);v$l5iIp!y-nksRɜܽ-Пok$ĨLIm9W!nWDIb#(_潽x㞸mo'8ZL}Y^@I"v9F2rnۇ/ K),xHOH(K@K2{G4LG]'|&*%.Ⱦf0bԜ{GDFY{L[AGWO\֭tS^IvZot)VVzuezqUI𽃑҉-~R4>\v%BdjfȿuGKNrxPK^7jx4cYߪbKF"~{$.%iz87,2gQ\rшwpG˒7yD<B%N$N.'}N.2.4_DдLso?O5nc!d>a)o~.V1ꬵ4W >yErHED'ֶVi{Z W3c657߸0υ8G$ Ɔ ’<#)T*.Cq9-5CR4 y,$K$l]S=m&mYjƳ1 un΃fy7MVǜfpynME#e+o1nnnqoG$̿#e~?F$x2SAy o.wRsɠ_ttu#ێWm !YNZ..S{jp'"C&H0:M){-[XLf[_;?=Hʨpm-Ma0TԔ W5sBbTII Cu&ƪˬDWҮB rjU/YuE͍LuC! uU/j9umMHdq2TӧXMuEI Cu(YE~vks#Cu$K"/D$d˻e!u )9 qB}y1Feҕu% Y IAQW~ZRN7o/Ru1a,QN iߏ_0 I,Բ1L*-嶵45`&P0Df(q|cUYscFPrT)"`*7>vlB3TtRm*]I;d #NmT̩lm`BcRem\"*F&KH3D!)uTWEbQh Ab4V# J".wKEP4TsmS!Oc"XwAL\N>WN7_DITi:bT&%\ CA7aT)UP"xEt9bF;tv%T)KXHEH2ʺHY68߿q^e_˷w^` |4>I;".|aR)i$щ'8͛79T) / Ht2LLBF(4&Non/K!/; )4_ZGy kf-HiT=yQxj` ׀ B@0̵kBl6%|2֭ 8@0fðy@/?6FLL  K /ALL K-fϞ AK /%_"/a!M|Z^FjBdd~}!=?-yIvzBvvv &&&N䤢"##*=jnn.//offvor or---61gΜ133777?z(R%%%]]]//zae~/^1cG htߟ^vSN_zX$444(((776wܹƒ\|!gjǏ8qbw˗/:tpsGmnnظiӦ͛윝]PPzEQpu51cF3fAp%{FXXݻ]]])mFݳgXgo߾‚L&[XXl߾O?~iii9|eP7O-EDD퇆Ξ3gBQTT /d|)))2lnn~1a$d#@ veggGڵ 0*r+G}wɃD ^|ĈYYYݻ8x񢺺aw-++]tYYY@@@\\\iiikkknGK.upp8q0Q L>yi,,,NKJJJ^tf}|[FFFjhhܸq֖%!]?iii!aryMMMGٳݻHL"8qbAAĉ{иaYɑ y(2?(//[pWY#@QQQ%wrD7nܘpo߾=sL}Ass|||~Gbִiwرxb[c_V\In``ZYY&`Tng̙ uuun2JKŊo߾r{{͛7?x𠭭mذaVV?L4M"͟?!!!=ɓ'WWW/]H]]~g>|gС!]]_6Q@v-[&&&fccs \@WY#@?ix _'/6=44˗&?3{cbb̙X@3@PPЊ+FgHꣻt8FKL]*Y K"@^g4{l9$ ,苠@/?6y /-bO%@^y /^ 3޹qܾ徸0zK^zF۶mp`*< /a B_h@^^xqɄ/^%RRRÆ 7n̙3!D]kk5k"""Z[[ykkk=zѣÇC^>/xp?VJJF7.==v5gggFyAʊNdUUӧD۷O2e$N^:''G777kjjs$///&&F,Xp9_XXX39s())d555v+yt/%%RЫ?V.ާɋ`0zusr}:> Ippp``  b͛sţw[N"n߾=bXSwVf𒒒uְa:`[nM7.33S[r'=:;;fgff^rСC߿$oBp8NNNׯ_'?S!APPЊ+Fg%_ Ʉ oE544888ElݺU6KJJ&MaR"uu6HJp%%޴B_b 6((HJ>Gp%%gӏ?a?y |;v(++ݰaoyxx6nH&''fжmƏwiӦIJJ***=ٵk3!/+[~~V^M=zynnnbbbccMx[fee 4hĉ~~~˛7o233===qqqk׮?uTxxիWgg삂Ћ/vBgϞ=u?>qDOgeeuU>ZMMwٝ;wƌÿ?CL߿Jl4Ϟ=~zZZZllwY$\]]I$DJLL$Ơ|(@"~򥞞+JKJJJ^tf Xv |Q[\\ o0/u###n;wSS#Gv8!gcc-L"ry ~L8`ĉĬ{9::D?~ϟ?ǧo.}͛72dсJ|K@nnu:xܸqDccիWM6LoW"!!rJ|#]rw|. 441&&ͭg_~ƍgΜPWWw-S(++߹siӦرc$7Ass|||[444Ν;{ ?Lӎٱcx;3>+QQC߷fruu 8 yIoqᴴCjjjnݺ_Y;7oߖ.]ZlYppСC\r a_b @t4 V^r?tRooI&uU>a呑cǎ%H D׈'O֭[gff&%%%**0iҤ?'8zADDD0 322JHHf.]F2 kk렠tQZZZPP̙3 &//O9Қ5k֍7n}vccc2,--=~9ss1 ;|PP>B'OZFFl}܇mshh˗/G0L!v>_ C@?!>y."##bŊSg_|@ 1quu%NN}y½KRRҁ -۶m^ zKz&k׮_i  ǎ tOgg $ti/_,--p8#FXl%Y҃n\7KKy^ݽy6"/|xy6%/ܣ%@^ ȗm钒b mHHH|Ox"22xsjB|Q .$^:;; 4_'gϞUTT0 nwrq?~>y(B(++ ++Y>r}}}F{=/111qvvuvvF͘1w.H|EEE#G8ǹ}6ֹ۷owkM?E>~8Grr2">}RBBBRR1##4FM2 }8WBŋ-,,TѣGwyxxHHH˯XwVVV4 y NP(gϞr;C&uuu;vm$\N]r0O333 u|\.˽u떬[)<<ɓ'Ǐ?yg_^v !dhh˗X,ޒ)S-~eUUׯ766>|ܹ,UUcǎ544-\ÃhD__޽{MMMxСCwUUUp߿?}t|Aݿ$%%iiin7Y;nW0 .466>zhРA7obwnݺu\=zmmoLTz=yv zMOeoo;h&&&&&&޽suu%f%%%^r۝鲿$++YYYd2UUZ#F&LZ]]ݷo⍤XZZs_|*677t8vz/Y 1nW{yyM<㣋  聠+V+7}كS9$Qtvv!_^ZZ~ؒVO{ 6iӬջBOM6m㤄7;)))_ ;{l_[[rڈĘ \XXXttVtt֭[?z?r;vApSGr. {=}}}xD\'\RR;N/ T33xJ;w\zJ/oݺechhaYbb"q'!!Ao|w7ROՔ>2%]}8hbb25Ϻê]dÆ 7oljjzՂ rccm۶솆K.k|||}}}mm7qx{{{xx477߿ݝ%`/x#iԭ'))|G|<ޑu_$88xEEEĕ&...OvvƍgϞuwwWVVF 2$((HOʕ+dsoӫfϞ]PPvZbo|6ROՔSHHȆ RRR,--}}}@]_رk…%%%W&fEFF5@p=|u='/IOO]TTo <_./MBHX@^K /@_8l68|3o޼.uuu99>@gttt$$$ 9Ϟ=;rݻw+Tŗ/_nee5{ǏST_Bxx'm3lllO :Kۃ;s)Ey޽{,Ydɒ%Ktw2___ee{yy,+22IYYYEEeٷnݚ0a߿bEEE988())ihh,\ _gmoohjjzivTUUeeeۭ4::QIIR1;;SS[[SEybXvwwG6lXNNNBB_Y;vزeKNNNffΤI6l댌 999//yyyiiiҞ,%ܼyc͚5yyy'O z*NXXXPPPNNNڵk6m=w۷C$:K>!D!ix _'/n›R\\gϞocک377 p޽C⳪ B~/+++ Jtkw&LzѪUvW $862 #// %:::44466VT?8ÇOHHPRR(}^nwxPPЊ+Fg؋ƗDEE={/IHH PVV?ɱX,555>7!^"*>]]]oy!7CyѼyX899w~ff|n7|d2Ν{s'''wwwHJ/ٳgB(55uiiiiiie{vŠw޵ 8%r3u\ ;mmm$pzmm̞=]0%_͐;~8ӧlwFab!x)*K趋/;VYYYCCcȐ!k֬FK|ڵk=<<޼yw円 //(tCBBBlllZZ$^sNss˗_rB>m۶mٲHJ-*..NOOK|!1bDy@y ..j_߼y,]]ŋC贿dBtWYY A :t~kW^PP'N@ǀ?l߾ Ϟ=?~M-0@7HHHܸqcѢE?~lZZZJJʶmϟⲳ>|hmmmkk =%_|Z0@^! `K /p\K>k֬Yf͚5_x‚Jjii=z(+r N>meeEDEEdcǎ}0̙3Æ Rt:}eee,ʼmii)!!!))蘑qu{{{FѦLB̌Bhii9rvϻ΂ ӓ`0 mmmOOn-{7n,,,***׮]Kڶm[DDnmmKBBBN:U[[{̙͛7_prppΝ;_|)--l2a c=z-[/_׌]hѦM/\?. «zeKK@}}ӧO>}Z__nv=+((JJJ666.]ZMM">JIIᝋ/?"6nx}uu'N444644yɓ@τzxx?~~ O>vyŊRRRx͛_~$}&/|}FFƽ{.533/sNpp.JEݺuKp;tBBW Dee%ӧ=k]`>uܹkjjRT|y/~x̘1|}}w#P]]?Zredd0' /<jÆ 7oljjzՂ rccm۶솆K.-\Pp;))))))>>>_enj{͝;g$%%q88WW Jcc皚"޽{IVVaw?IPgQ(Txռzƌ3f貦#%%5vXٳ,kƍAAA;wٳ7l0mڴ֦hk֬Y;NNN!!!6l 02OPPP@eddt8/@τvvfn*M X?yɓ'OܮpРA׮]-!xɊ+[(QPP8w,DR888tX^`>aʔ);w6mڶmdrsssIIIbb"~n{ʔ)(:tYO<';p8]&GFF '}]VVVSWWǗP( yZZZ@gbeer;or~:>iҤ{ڳgԩSi4O#A7 ݻwϜ9s…F*`llacc!&K_~F1Ԏ&>n%hjj"^|rOxBHCCJ:|ȑ(%n̙cǎu8ȑ#!a _ ܿcر!rbbK@k޽K,IKK[dɒ%KxttӧB...W\S^^Kcb444.\{beb"22IYYYEEeٷnݚ0av+**ai׎lXybXWh IDATvwwֲ׮]ݴiSnnsn߾ƟB8~ Lf/刈༼4iiiOOOaڱcǖ-[rrr233utt&MaÆׯ_gddyyy5o޼f͚'O_zh',,,(((''7,KB^^^G3fE P(:::@999?~rȑe˖=|d͛\ƆBXM6ܼyprrz)QxxP^w^>> MMMo޼qss#fM6->>~ǎ-"m˛SRR~ᇞn:??TS__Yf}L0`(**f2ٯ^*))?\2}twU9/>?͛SSSg޽{ҥ"K/("k׮o666(p87o\f !AvFy)www4|8Fɓ̼<11۷+++CXZ^d2!:` 0afllكNKЙ޽{JJJcƌ𐑑|$ t͛7.))yȑb33OBp>f333… KII(ݰsI aʔ)O˭[:pU%RYY`0:UXXxQ%an1{קP(rrrɁ(;E׭[!Ё]v?}O˃1fΜyY֨3f@ /˅1jڽ{7BhܹUUU999Fz c̞=`˖-mmmDaccҥK !yIxxYg͚5k֬.~12~~ NP(DauuudαcǾbv̙aÆQT:>}v̿>}RBBBRR1##4FM2h!tE333 uCg_ƻҋ/ZXXPT---8Qڧz ! --k.s=p͛78n:]]}A|I^`0 gp֭[ړ'Oי:ukAAAMM޽{ϝ;G 9uTmm3g6o. ޹sguu˗/-[&RAAAaaal6;??GݲeKyyy^^񚱱-ڴiSuu m۶EDDV\TUU{ ]xҩGfysrrcbbN/+)) Z[[/B41AR y;z 񲢢BRR6V&&r6-!ڱ￉Y)))D;)))ҥK\!Yn]/?ܒWaX~~>CN>=wܯ ߫vE{=}I=qㆵuO~-ΎiӬՉY}ߡCL&NC^~o NZZڷ~ۮ hzz#͛7B BxxxXXB())i̙BZw),,,::ZKK+::t֭_}4A'槼l6Nw}ZV$''WVVFGG/ZH&&&ƍ_&$$tXmذax'ANN v˚|PHHH޴O277}233wuuF,de˖^k }>/ƍqi33quu>|x[[ۍ7YIJ=߾^3700Nv;߇ ҒvKmذѣF8q|NCݻW@KKKӂһwvޝXSSCGO`%Ԝ>}zUU~AڵkWXѮʕ+d-8sSSS_MuwG__͚5=xwrr ٰy Tkc&`ӢnGP,E)JܢHRI骈B>E)TyL1fgΙ93999XPP088å N>QQQ! 0ff> %??Ֆbbbo޼ẓG/^ [N`',>`itt0K[[XUqG~4zT&?Nyys萗߿EEELLLw+&&ÇS؆G  0=4%,,LTTB-Zٳ0 \|YOOoXR ~@ /vܽ{w֭555}}};v066TmmQ455.@^2$%+׬Yc##Q}{{۷!D@^AN8smذR|U" /XWW 钉V\?߿3NcA;wL%{@^ill$/400tdbb۷ߵkXCODzeːȫbccdee;+--f6j{0W7lp֭s:~8@x |ÓI 899^:ΙccƷ200<~BS7p@^KTO]ύ7KDDDTUU׬Ycccsim\\\ff&y$$$֯_nݺsm߾>P 8^?&Ç̙CJJH 69sZ5,Ubff|__|@^-8XГ'OtttFս>4YÃ`JKK .888x]<&&FAAOII)**T`n߾ḹ>}rwwDs_ /,,looBa455xp b䢣)M-9sFBٳgU[^^ (8;;)))Z!!!/^qℂ RRR "=2ףh,{񄄄)˗,YBxxx=>ΥTUUh49|pkkkxx8y m!!!gϞ544Dы/`uuu4-..; h߽{̌z:giiQʁiii@$..͛>| dffOPV^^JzJ* O>رCZZx2xܹLIIIc..Aysrr""%%E^BZOII ̔˗/ IYYي+`IYYYBBmؠsM6QUkO8qƊ šuM{=@m: .?ʕ+6m:v{TT++Y3͛7/\0!!á达>>>)8XgccOXZ֋-lllqFook:ee` CCC---gϞݾ}>JhxseejFFFrr2TN[[[JJ]hX /;r䈸8F$;;Ebaaioo'=}GNN. Ιmceew^TTTzzzssWaa!ZXXzjٲe .,++۶m|N^2*wwwffl힞}}}EEE^,--#gggRgϦ<5s___AA-[~m=.,,ȰR{}y|hϟ'{/( c~~~-wW%%q511vI&eӧO#"))ya?Gqvv&y`p( $i;wϟcbbBOO5kdeea1aaaPSSLOOӧׯ_[n~MPPpbbb>|8S<NH ]RR[~~yhh(\BKrHHHAA(ŋK.QPXXhaatRss9s''ŋGGGPi>N5{Ͷmے#""+**޼y w%%%D .vPmݺu/_ݳg@سgϴ%uqyyyB7o BD*++.\8JMM͛7nݺUWWBTUUA^o.+++..?bcc $%% 8-!!dd9ӧO!4ak蚚 J?000?| UUU,{ΝW^]~_^^@ X[[8qb˖-EEEgϞ]nX+looGP,,,>|0&&N0 X8Di,c]N Ww`+hkksrrz1J oذa֭9992ZԩSc]?k֬ޞDØgV@deeyyyU~CDD4^^Qt`ll<Kǹs笭G^#''}adddYTTTTTTRRrҥNw{ͼy,,,DDD^~wEZZZdeeEDDgZC[FFfZ999A&yVVַoϟ!))I500JIIyА}tt4|pK?P?>>@~@ 2rުNVVv,&D,,,IKfffXXXDGG EGG[uC`` fZx @%7??f(++BNqqqׯdgg_nљ3gFƞ&Q'OZZZYZZ /"""P(K?yyy4-**ITSS++++//m:::ttt***4]LL333''5k>}Db)++iiiǏC#;8,bJJJW\oi+;;իWceegee555zjNNSRRD ߨ|߾}YYYO622طo_yyyMMMhh W-# M:''/_߿?77'vXѣٳgwwwHHHܻw z+A NPgyYOOOSSӦMV^Mb҃Eeffvwwlݺʒ#;HzpǏwwwzzhki㽽xqBBvo߾7v߫w3 PQ^R__IВ%KRRRHO/">^by"RPP ##3J}bI?YA^xAzl?K5 /!BGv߇/%^}}}lllݣ'%%͐ƽFGG\rXɓ߿pϟ@1_z5q8###ݬYXuhdzg&El…Y`y i=NĹ%M"n  USS$$$'((hjj IDATaZX,W\\|FZѣ8_2KBBB]n]^^^^^82888ʊ==='"#GP6lD*'tL0QQQ hѢg(IVPPdիkZ[[_t CwRSSܜFGGIn ''gggg__ߨ3J:jKvԤN rrr.]J~Lvv6)cEEŢQzY``$333 O>P|C˧÷4uݭ[UTTرظ"39oܸϏ ;;MnnnPPлw DT%//޽{fffaaᐐ''In q0߾}+..VWWdyyyg.Hwww<ׇ]]]IU>>>===l毿jmm=ZGGӳ/''CS>o\xQDDQBBٳ(T²b Ҡ7o233333^z!^: FGssYfP(99h \2V)/u=yyy %""re:ƽΚ5 Aja,,,s7uppŋ?joofڵɓVsqqN4jC&Iׯ_HMM=y򤸸co|*J#mݺu֭%%%K444444F."!!B^B:604񓌍| R ߝ;wȫHL(,5jX})>MuuuJV\gjj@ubbΝ;?}f͚ b6gaa,߿ ۷o+++'I666jjj׮] "c&KTTb֭ˁqܹBK.9::_F3\]]###555%344LOOc522MHII~x?aXT3ɟ gʕ[޽v90-[ Aa۶mܹ3%% yEaaa;Ou%$$:ATT-lv) VZ!TVV:tGf 6 rܹUǏ_b799y#'=BBB666V۷ok׮Mddd _~rJoooє@;c/g$hѢoҡC/^%%%CMM۷oÌvF'%%9::`0ϟmܸy  ;j#66ׯ]:ꚓ{YYY///aaa??bbW:;;nݺ5)%0F******...7n`ee͞={<*1o޼yALW9n۶o^~]?˻k.i%{0j_EO+Wzzz:999::;ntE)p_@@`vvvphѢOfgg Ν;***&&&#a``000Є:s挡… ]C''mm8t&%%7&&& ?~b.R^^1gϞ[!bdddhho>/G %Z.cd={6y 77wKK˨ߝ'88KHHד qI__ѣG#ˉ3ן0 K.}xVN|%0ݻܹsÒCIIIzW3000ɩRRRZ~f^^|ʀymr助9i0F999yyyG߳gOvv7u֚5k6. $444 ۗcǎtNNoڵkcccGz(///333== `mmt%Z˻o>jh8O>Yfw)/^t]̀%A˗/&_||UN>};v,\PKKٙ‚%%%VGEEAl%߅ x./,,looB,`0QQQJJJ||| 111T_ C#_LzpmmmmAAASSӊOp8gkkKZ IIIX,VNN.::|p8nnao?l)XYYe˖ϟ?WTT,XÔ /1 rqqO:X[[988vM:s̥KÃdǟm3~~~eee&&&"<<}JK͔RUUE í%iiiٳh4z?^YYihxXX$Lm۶9sf```XyCCCzz5k DPѸ׸8CCÛ7o  4ۑKJJsqqPWUU%=^lYyy9B) 7)))zJJJ#?,##3VX;S"++G򶶶zzzΝpW:::qqqA/.\pyA 7mڄx|pppOOx}g(/5z뿐!?e[?ԣv8nǎIII\|YNNNVVV]]}ݺu7n 8^2!#Ix|[[[JJYsnn&qNN΢E#aaaioo'ͯ_[\iiSKdee\ &Ç &nٲ̌xd|@)vwwgff+,..+..ܱc$ޟ?+((زe˯gޅ===ᑙ;ʗ/~ƛ7oFEE"%%%__#GP(!HJ yՔ~aH[l066$44C^^w޼ynnnNNNuuu??AdޕX,v&Zjjˇ%%DFFFT2/3=/slڴiӦMӨ<<}Ѥ66600+L1>>QZZZQ\\zj ###`SSS!,ÇBhƣGǤ/]!m_ԏ͚5W\APrpqN8 UUUKJJ5=?Ǐ/^L,abbZfҥK555S%0;#//ܹ۷;wNTT ȵkDDD/++s;wn OT&%%$88/|/`F!NGM}…3gTUUqpp=z~ KMMw^FF##;GEEݽ{WQQXRQQ7]zQPP6jYPP|֐@Ξ=K8%:::99ñb TUU100̟?_EEe:΂=gϞ Җ-[feehѢ~QQ?c뮧Voo/y:r pv9A۫/_B Ќqqq//7oޔmݺxf:eeeE:::UTT())988{ѣߧHII5w}}l%<.AmZ۷rppppp={VNN.99>YZRPPC~۷o'>5]ݻwmmmIyyyfРlذc֬YGjjjؔttt%,EDDO.\ LEco~֭a_v߁htttco%n'OJYt{ܨj`ukjjH?SWW޽{UTT^x!""xYYJۤa| fҽϞ=BD3^~>9v:ݻ)//_RRvڑU/^`ff޸qK111(((PO_YXX߿qF J C,ٻwիW ;;;%i&-- A {NLLl*4ZQQk+w^bbbcc#''䵛6mRSSsqqp孭/_W8!!::{n߾755qqq]rRMMMaaaeee歷mppÇif8ЎѐjO: Ȇ  P4F:K,/_fޮcccC -ZTPP0$CtŊ)))l555++TQQ!6+VXvA~FttA__gϞYXX dddhjj"e˖_['$&&Na1\&666sQSS{I? ޽{jjju4###K-Mo|UMMŋ8uԦMWjʚb8`kk{mҥX?ӧO#'1#q/..:**j۶m>>>8oÆ ,x'''mlrrr"""!!!9Ҿ q ȶ0xyyiiiP(===MMMss{dTF۷o߾}kX,ǏV>c{͛7ߏOs+L2ADvnT &0gT7>`E,BeϿu_RIa܊[XH_Er,/_RUtd&qdb8Y/k?WU,[Zrp΃ds4㔟8l$+++[ZZgl|ddd݃O=|ի6)ʺsΝ;wv7h| V~ՓqM 8>>$/ݽY/٘.',eՍՍ7R%:b1e5k>H-?,`[gO\Fy KOWH^M.-}`ˉ&ثɥ[F\jdL*eݧ֎b.Ftuu!1T$---3n} Dh- cM40hQ?U] TJJ7Qo" M G⢙k_G%'''''spphkkGDD|JT׵TSYVVj D2 ?\|h%f-՞!t;$Z;8.dkk;%sKL/%%%ênܸzj QׇPD-qdV`\ljr*K~{I w IܜO_߷|oT?f"=Ιkkn qÎ1}5)${i33a=zBT넱_{Aڋ/'7˱^{'EU*ZS3ȹrfyeVZy]s;=(lEJc#?PY,FK<*dAPdjjjxe˖uww?~/!!APPCc^|'4jժ_ܼOx"~Tyu5+ϙEv@V^U]]`jjd_ ޿NFF틋yKy1r%LB"fj./gK{kgϥx_lĞW}$]N mcffhۡCZZZ^zEk׮ׯB 3ygx86dAL`}vLL̰ˈlmm---O< !B0xQu '[geOAL`JHHXjըWW]%Ky_6lh@CC7₂%%0y}9$Ν !$?*-- n@y 0yXlhhʀ@{@"##>}*##g A|S^i9DÓyԩ?233dggKHH@pY^WWWWWWŴKy %@^ Ay %̗/_  /.\ppp?xLLRTTׯ׭[',,b555޽KZ$))I]]EGG-))IKKd`444[ZZHU#_LzpmmmmAAASSӊOp8gkkKZ>փḹ$t`0)))Z!!! IDAT/^"P]]MLf }^aCCCܔ>?~JJJ?ʕ+8I|vZ ~~"aeee!7`0yyyRRRħmmm-jhh V ;B*`0999'Λ7T"--M\>b0Tyyo19ݟ6XU3 =}mmܹsa#`ډyضm۰¸tD'..͛L"33SII媪˖-#=vpp466VPPXb#H %>(++[b$WRRsR0y rwwgff˶oY\\WTTA&߿ۻ3##ҒXgw9;;Or544?WPPe˖_[>R001Rm˔9ׯ߿ڹs'隔-[?~311^vXWTT488cbn@@wee%䎇zxxΛ7CLy]gggQQQss3//ymMM͋/Ĥ!\`jQ8KZc^300pͻwƮ.,+##cnn~2Ǚ.CCC w200TWWoٲիW(*;;F-YBGz$ikk'/訪?{lrr2J.0ݻt5|jjj02o;w=z4%{L4啟/$$tڵꮮw]~]HH(??5CA>|{n777RR ŕ+WsK~3S||j۷o LJ @X !Gbaa0ZPPPPP /+fffXXXDGG EGG[0(**Z{66>Q@;|}} DYY5C899-[lƍ嵵7npww򊈈v=Ǎ!ٳgCt 6ŕO >~Gښ⋱xʳ -Ɖ',,,P(T__ݻwsk׮Zߟ8 ?555;;./L]߬DAA^ ''7lP@=JpRAAƍjjj$&&8qȨ BZYYqqqA%jAOO/&&Fb;B>[_qÇ5>>!篿:uTkk>|ޞI E P9*uɵk.]tKݻx}W瓒155@DEET7oI>>yyy(JMMڮKXXXOO… ݻaÆ_X'QQQ! @=2*djjJ>iY[[OD~Ͷmxxx=gggi\ ܌=N'f?qL%3 a!D m60.Z@^K /%s^Vy# /%Ky %`0K3//|w<0Ϝ9cmmMzѱhѢRzQQ` ? &..NCC_XX޾T5Ťo455xp b䢣WH\IIIZZZÖ}׮]BBBh4zܹnnnmmmS$L~3V\9NUjϤE666"""(SSS=9=yd۶m222LLLX, !!w ߝ }^aCCCX%%q.U[[t7oް#yfAV\YQQAGG` ooomkk~:jX;I% fAAA ~~~󏠠``` ڵkm޼̙3:::_޴iq=;}[;wnҥ aaa3—Q`` ,Y@UԤ}_vgN~(g2#6껄'?8?l$oNc}۷jw" `۶m  Tt=22A.\#vqp6d``@w9|%KP(ѣGǹ*`0nmm '/IKK#2$$ٳh4z俣ϟWVV&&%䂃hLNJnܸ'$$ݝ7w[nMyۆפ/ '&1̈)))EEEUWW[XX rر 3ɛ'۝;w"r &%qqq7o$33 edd^ӧ$&&Rg%%%ISA͛Gzɉ y i=%%%666SW/_$RFFfX~}X޽ _d4d;w 8a Ν("" *8?l$+//𐗗gcccddEq&o^݋ڸqc]F)'Vkeeeee%̜8qBr;p9sryrrre|ĈҶE}}eoo/m !tK~ gϞɱzo >oɱ>|8YOa}I||ԩS[~#~*?D~~icccYYYG5͊ԇ>iTvY ˌJeDD!Cr\.2d{DDRKIϗiHwOUWWt3gά^ɓ555JrԨQC/Quuv.Dq…TTTܩƎ=k, [rpp{nqիW__?o޼͛7:99[nܹ =%>}zDDԔ۵~֭[~ԩ{?~QFTTTHHHVVVcc˗9I!VZjժGGGBI%'Nr!!!&MZ`aPPJ/Ν;+++mll JZre6mZ\\\TTT>}~KTnݺ5<ѣG3,sAo߾BË/ !OюgΜB888zèٳgT*]| <EY៩飯M~***KjB !\ -cbbrrrrss?C@h^t~hss%KofRRכ޽{۷?^jvZݻwIDAT9rÆ =>c} <#t/}//g}s̱200vvv9996?k&9sӯ^S/gDG#۔899I ]fΜ9s̎:)))))I$##W]| K\%@. r K%\@.r K%\@.r K@Ϥ]knn8@B%cSYY @vTu]K\'ֽ]qQlƌqa Z[[%?蔎K@wA.r ܒd r ~Eee… #055@.,ZH__XqڵEmڴa@.M2LV?ť4##YP( OO[n?'KdzHKK7n޽{7oT*##>  … JL.;99%''Kh4^zIaaaqر;lmm ;wﶱ100ݱckYK&&&&>>lذaSNذa۷]6`@WI#GT*ULL̝;w4EqM0>lRUU"xg͚U^^^[[}ُ?\+...))n߾}~ajjMNNSqqq6?^N+ܫؗ_~&^={VwG!ĹstKmhҤI㩭8pIAAnayywܹseddŋU=rF#UO8Q+;vLh4}Wy~c\| xKB;;;L{...+**/^lee/LLL***ZGGGNNN!!!eeeUK,zJrȑ];7xCڞf̘>HvĈk֬B\reٲe1 ;6;;}.66P#""_TTQ3~+m8qbm'OJU@./++hxe>::ݻ^pC5kVvvQWWimm-U)Ǐk/ܸq#<<ͭkR T*Uxx|!!!MMM*bcc%Jr֭&&&SLі''' 4wޫWyHuz=hРޏ[ZZ !ƌs=[;eŊFFFϏ3g{Ŋ^^^FFF>>>:Kf\y]6o󬺺G͵cn#O^`_[y7dnܝ| x|tRsssIII``ŋsωG77zʕ+~s??????F ?u@.+]vY7 @%!<Č38Gc} K\z}!<%c7/$kg8u ⫽ɄIENDB`gWidgets/vignettes/label.png0000644000176000001440000001224611406427017015663 0ustar ripleyusersPNG  IHDR~ pHYs᣻tIME9(:EIDATx}p{gg-7$eV(Aڭ}*j:׫-VWd3{읢p("Y$ y yu^1&3! Y18MCO7=a I'"e_wHIɥ@s̝Oq8(pG5J"J;*2*u\/Z~OڒNDZ~*O 0_Q"JJJ:0 7%0D$͙Bos|NI</Gg Zk^ & 0ԞM7F~YUV?ີkAgKM5İ.\nd}-N\xnMI5ŧ}Q0p>-k[oNMI\xrw:r y<;6mQv2Dz (;!T"Z(;!;5qnWuw!&畘YS|ڈ#-Y#Z fsz#KW +/\Qt)RymnHqPCcjuzAcYttj: J"lWi4kܮ5ޕC 3=])p| r̺'gBU֬c}^ÇR=ܘO>#O6ve.;;>"mklnOYMsEֈ(Ntj":qKXLkֈ(Iz ?_8-&!F6hv/3Y/]j`goT|bcl:+3gOh߸uRe6v_.)&&Wz :|`@K 6-R[{mQ- xhzjлnf4~{G̴?1! ]nT*/^Z]p'+(U͚m#"B93fdT kIi)ԤX{_ 3#,ྙ`p˖H vt:Fio0H'",5ި%f12 hh%nRpa1:c!^(rpXbOj"6n9f~Ţ{6n*a-^6[g/X~QϯT}=1ChZ;pW1Ә^ q7ۺ5CDWU5 TMp'T&se7g,]l  bBY;:_|镺3Ӟܺyo_(Ťe]\4KEUsMNf6JZaoJDmfII֖DTzrQ㿛0&ܴ1SDǚ)nپv\,t836mٮP*طзEyHDF9JE~m\ td[ЩJĮ^"JMIr9VEDWQ$v=={_vfkyUE"o68;;LOD11eZg8~ ^٢S2z郣7]nz.FID>IwSVQF*&U*3Y_aј1 1mڪDWS/6mUp6*ce5x^.p~ߗ}>ߟ现}>_e]%/q~zjrj}>_FD(1ሎO̝>+4u_׭5Dt2.!);o^v|!b:^CD/&dΛ7Ddtwu}>_b|\eŞW]]]Sn |: B̙3Ii^@m^7BnSǔ*~ي_v }W Nͷwj4Y*hxQdSsk^KKM5zG(:}`ï_auz eI %^HVFdl2@'"Fmڬ( kxbVSnY6Dj6VVZm6.6FfcӐ#B>Y?zdy7w\,̙>3b=^Ӿ~,uhh]r_gT*8utu,;%ǩZںf˗+ %NmDTrSuP(Jq \.57rLtO~ Ͳ]*9b/0̕kVŲ{sZeZAq!wgcsTYQiNiap׼a|O?4ƾ]2sfoںS*7mAD% 񿎾SV皡s5g΢iс%)i޾.~3Y.Їl]^"eCM^QdY'JJ/A%eF?yï8[ q#=3-*9<|f,=qNtuVKقs<2ݮ>";g/R.,^;'_ju V.f\? sT+~VWr?w*TtOvޣO܇8O5k7EWSQf=*1=khu:5U=,x-#SU]Q7⨌>H S;axꚺĸ 7[- "ӯUTTB l"b+==)ze6Ɂd^ w Cޜ yɛ;ɛĄvܵ+2-9%V?aSr[~{LNI 7mbg~gs[gςV(iYsݭu ===7.$ZiniY%DI1 ՚\YUͩT(iuѻ7F~ÐV/;ynfrtrRgSr샏?3tRQaL>-:&.>I4*UgWlJJdQlj0da``PEN;_uν4Vxhݦ9Åv㺽'*z2W:f市 Օ7jSg["l@J;StQrn{;QkHLN 6F<終Naֈ>@`X:GD^2#6>DR^\[]Ҕ2h(چOOSf̲DDTT6Rn-2s{+e4ZdbD XX#QdI9>Kbl>7M^*X` 1v#p7jcCxR]>{)36?K)6RaI(I2Li8M VG_[&R`T6Tͅ|IBއ9 ,|D4#1, 8pGe  @p 8@p@p 8@p@p 8@p@p 8@p 8 8@p 8 8@p 8 8@p 8M,OhyuƳ]|.Sg 8=hѢr~~~NNj}CK/mذ!vϚ5v,Zh쁲,]tiL&ӈف/'NhʕrxYY?|>b{{f͚'N={~m۶mϞ=Nl…P(p}uҥqvÂYf\3..nƌ{)++ #\reYY޽{O.==`VƯgyp``ԩS֭ _ رcG7oV*DT*7oϯZ=ӿկ[*ŋ=>/'''?Iׯ_O:g/QTcl޼_^l |'bccӟ?, p'=WI= 8 8@p 8@p 8@p 8@p 8@p@p 8@p@p 8@p@p 8@p8 8@p 8@p 8@p@p0(ǟXUW"zxs0[(TIENDB`gWidgets/vignettes/gWidgets.Rnw0000644000176000001440000020525112313703442016340 0ustar ripleyusers\documentclass[12pt]{article} \newcommand{\VERSION}{0.0-7} %\VignetteIndexEntry{gWidgets} %\VignettePackage{gWidgets} %\VignetteDepends{methods,gWidgetstcltk} \usepackage{times} % for fonts \usepackage[]{geometry} \usepackage{mathptm} % for math fonts type 1 \usepackage{graphicx} % for graphics files %%\usepackage{floatflt} % for ``floating boxes'' %%\usepackage{index} %%\usepackage{relsize} % for relative size fonts \usepackage{amsmath} % for amslatex stuff \usepackage{amsfonts} % for amsfonts \usepackage{url} % for \url, \usepackage{hyperref} \usepackage{color} %%\usepackage{fancyvrb} %%\usepackage{fancyhdr} %%\usepackage{jvfloatstyle} % redefine float.sty for my style. Hack %% squeeze in stuff %%\floatstyle{jvstyle} %%\restylefloat{table} %%\restylefloat{figure} %%\renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} %% Fill these in % \pagestyle{fancy} % \usepackage{fancyhdr} % \pagestyle{fancy} % \fancyhf{} % \fancyhead[L]{\code{gWidgets}} % \fancyhead[C]{} % \fancyhead[R]{\sectionmark} % \fancyfoot[L]{} % \fancyfoot[C]{- page \thepage\/ -} % \fancyfoot[R]{} % \renewcommand{\headrulewidth}{0.1pt} % \renewcommand{\footrulewidth}{0.0pt} %% My abbreviations \newcommand{\pkg}[1]{\textbf{#1}} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\RFunc}[1]{\code{#1}} %% no () \newcommand{\RArg}[1]{\code{#1=}} \newcommand{\RListel}[1]{\code{\$#1}} \newenvironment{RArgs}{\begin{list}{}{}}{\end{list}} \begin{document} \thispagestyle{plain} \title{Examples for gWidgets} \author{John Verzani, \url{gWidgetsRGtk@gmail.com}} \maketitle %% Sweave stuff \SweaveOpts{keep.source=TRUE} \section*{Abstract:} [This was updated last for \pkg{gWidgets\_0.0-41}.]\\ Examples for using the \pkg{gWidgets} package are presented. The \pkg{gWidgets} API is intended to be a cross platform means within an R session to interact with a graphics toolkit. Currently, the API can be used through: \begin{itemize} \item \pkg{gWidgetsRGtk2} for \pkg{RGtk2} package which is the most complete implementation. \item \pkg{gWidgetstcltk} for the \pkg{tcltk} package which is the easiest to install (for windows users) but not as fully implemented or polished. \item \pkg{gWidgetsQt} for the \pkg{qtbase} package. This package allows the Qt toolkit to be used from within R. It is being developed and is available from r-forge. \item \pkg{gWidgetsrJava} for the \pkg{rJava} package. This package may be deprecated in the near term if no interest is shown. \end{itemize} The \pkg{gWidgetsWWW} package is an independent implementation for web programming. It uses the EXT JS JavaScript libraries to provide R to web interactivity. It leverages the \pkg{rapache} package for server installs, and has a user-only web browser leveraged from the \pkg{Rpad} package. Unlike the other implementations, this package is stand alone and does not use \pkg{gWidgets} itself. % Finally, a partial port for the \pkg{RwxWidgets} package is started, % but awaits completion of that package. The API is intended to facilitate the task of writing basic GUIs, as it simplifies many of the steps involved in setting up widgets and packing them into containers. Although not nearly as powerful as any individual toolkit, the \pkg{gWidgets} API is suitable for many tasks or as a rapid prototyping tool for more complicated applications. The examples contained herein illustrate that quite a few things can be done fairly easily with more complicated applications being pieced together in a straightforward manner. To see a fairly complicated application built using \pkg{gWidgets}, install the \pkg{pmg} GUI (\url{http://www.math.csi.cuny.edu/pmg}), which is on CRAN. The \pkg{traitr} package implements a model-view-controller programming style for GUI development. It uses \pkg{gWidgets} to provide the GUI components. %\setcounter{tocdepth}{3} %\tableofcontents \section{Background} The \code{gWidgets} API is intended to be a cross-toolkit API for working with GUI objects. It is based on the iwidgets API of Simon Urbanek, with improvements suggested by Philippe Grosjean, Michael Lawrence, Simon Urbanek and John Verzani. This document focuses on the more complete toolkit implementation provided by the \pkg{gWidgetsRGtk2} package.~\footnote{Occasional differences with \pkg{gWidgetsQt}, \pkg{gWidgetstcltk}, or \pkg{gWidgetsrJava} are pointed out in braces. The major differences from the \pkg{gWidgets} API are documented in the help files given by the package name, e.g. \pkg{gWidgetstcltk}} The GTK toolkit is interfaced via the \pkg{RGtk2} package of Michael Lawrence, which in turn is derived from Duncan Temple Lang's \pkg{RGtk} package. The excellent \pkg{RGtk2} package opens up the full power of the GTK2 toolkit, only a fraction of which is available though \pkg{gWidgetsRGtk2}. The \code{gWidgets} API is mostly stable, but does occasionally have additional methods and constructors added. If a feature seems lacking, please let the author know. \section{Overview} The basic tasks in setting up a GUI involve: constructing the desired widgets, laying these widgets out into containers, and assigning handlers to respond to user-driven events involving the widgets. The \pkg{gWidgets} package is geared around these tasks, and also around providing a familiar means to interact with the widgets once constructed. The actual toolkits have much more flexibility during the layout of the GUI and afterwards in pragmatically interacting with the GUI. Each widget constructor in \pkg{gWidgets} includes the arguments \code{container} to specify a parent container to place it in; \code{handler}, to specify a handler to respond to the main event that the widget has; and \code{action}, which is used to pass extra information along to any handler. Each widget when constructed returns an object of S4 class which can be manipulated using generic functions, some new and some familiar. The basic widgets are likely familiar: buttons, labels, text-edit areas, etc. In addition, there are some R-specific compound widgets such as a variable browser, data frame viewer, and help viewer. In contrast to these, are a few basic dialogs, which draw their own window and are modal, hence do not return objects which can be manipulated. The examples below introduce the primary widgets, containers, and dialogs in a not-so systematic manner, focusing instead on some examples which show how to use \pkg{gWidgets}. The man pages are also a source information about the widgets, see \code{?gWidgets} for more detail. For differences between the toolkit implementation, see the man page for the package name, for example, \code{?gWidgetstcltk}. This document is a vignette. As such, the code displayed is available within an R session through the command \code{edit(vignette("gWidgets"))}. \section{Installation} In case you are reading this vignette without having installed gWidgets, here are some instructions focusing on installing \pkg{gWidgetsRGtk2}. More details are found at the \pkg{gWidgets} website \url{http://www.math.csi.cuny.edu/pmg/gWidgets}. Installing \code{gWidgets} with the \code{gWidgetsRGtk2} package requires two steps: installing the GTK libraries and installing the R packages. \subsection{Installing the GTK libraries} The \code{gWidgetsRGtk2} provides a link between \code{gWidgets} and the GTK libraries through the \code{RGTk2} package. \texttt{RGtk2} requires relatively modern versions of the GTK libraries (2.8.12 is suggested). These may need to be installed or upgraded on your system. In case of \textbf{Windows} you can do this: \begin{enumerate} \item Download the files from \href{http://gladewin32.sourceforge.net/modules/wfdownloads/visit.php?lid=102}{http://gladewin32.sourceforge.net/modules/wfdownloads/visit.php?lid=102} \item run the resulting file. This is an automated installer which will walk you through the installation of the Gtk2 libraries. \end{enumerate} For Windows users, the following command, will do this and install \code{pmg}. (Likely you are better off with the previous method.) \begin{Sinput} > source("http://www.math.csi.cuny.edu/pmg/installPMG.R") \end{Sinput} In Linux, you may or may not need to upgrade the GTK libraries depending on your distribution. If you have a relatively modern installation, you should be ready. For Mac OS X there is also a packaged port of the GTK run time libraries available through at \url{http://r.research.att.com/}. When the author used this quite some time ago, the \pkg{cairoDevice} package failed (this may be fixed by now). As such, the the macports (\url{http://www.macports.org}) project was used to install its \texttt{gtk2} package. Once macports is installed, the command \begin{verbatim} sudo port install gtk2 \end{verbatim} will install the libraries (although it may take quite a while). There are more details on RGtk2 at \href{http://www.ggobi.org/rgtk2}{RGtk2's home page}. \subsection{Install the R packages} The following R packages are needed: \texttt{RGtk2}, \texttt{cairoDevice}, \texttt{gWidgets}, and \texttt{gWidgetsRGtk2}. Install them in this order, as some depend on others to be installed first. All can be downloaded from CRAN. These can all be installed by following the dependencies for \code{gWidgetsRGtk2}. The following command will install them all if you have the proper write permissions: \begin{verbatim} install.packages("gWidgetsRGtk2", dep = TRUE) \end{verbatim} It may be necessary to adjust the location where the libraries will be installed if you do not have the proper permissions. For MAC OS X, the source packages might be desired if you installed via macports, not the default ``mac.binary.'' Use the \code{type=} argument, as follows: \begin{verbatim} > install.packages("gWidgetsRGtk2", dep = TRUE,type = "source" ) \end{verbatim} % On occasion, newer versions are available from % \href{http://www.math.csi.cuny.edu/pmg}{gWidgets's website}. To % install from here add the \texttt{repos=} argument, as follows: % \begin{verbatim} % > install.packages("gWidgetsRGtk2",dep = TRUE, repos = "http://www.math.csi.cuny.edu/pmg") % \end{verbatim} [The \pkg{gWidgetsQt} package requires the \pkg{qtbase} package which is not yet on CRAN, but rather is installed through r-forge.] [The \pkg{gWidgetstcltk} requires the 8.5 version of tcl/tk which comes with the windows version of R as of 2.7.0, but typically needs to be installed manually for linux and mac machines, as of this writing.] [The \pkg{gWidgetsrJava} package is installed similarly. However, it requires \pkg{rJava}. These should install through the dependencies, so \begin{verbatim} > install.packages("gWidgetsrJava", dep = TRUE) \end{verbatim} should do it. The \pkg{rJava} has some potential issues with the mac version of R that can arise if R is compiled from source.] [The \pkg{gWidgetsWWW} package is altogether different. The package requires \pkg{rapache} to be installed to be used in server mode. As well, the apache web server must also be configured. The package can be used locally through a standalone web server. ] \section{Loading gWidgets} We load the \code{gWidgets} package, using the \code{gWidgetsRGtk2} toolkit, below: following <<>>= require(gWidgets) ##options("guiToolkit"="RGtk2") options("guiToolkit"="tcltk") @ <>= require(gWidgetstcltk) @ When \code{gWidgets} is started, it tries to figure out what its default toolkit will be. In this examples, we've set it to be ``gWidgetsRGtk2.'' If the option was not set and there is more than one toolkit available, then a menu asks the user to choose between toolkit implementations. [For \pkg{gWidgetsQt} use ``Qt'', for \pkg{gWidgetsrJava} use ``rJava'' in the \RFunc{options} call or ``tcltk'' for the \pkg{gWidgetstcltk} package.] [The \pkg{gWidgetsWWW} package is different, as it doesn't use the \pkg{gWidgets} package for dispatch. It is loaded directly via \code{require(gWidgetsWWW, quietly=TRUE)} -- using the \code{quietly} switch, as anything output to STDOUT is sent to the browser.] \section{Hello world} We begin by showing how to make various widgets which display the ubiquitous ``Hello world'' message. \begin{figure}[htbp] \centering \begin{tabular}{l@{\quad}l} \includegraphics[width=.35\textwidth]{button}& \includegraphics[width=.35\textwidth]{label}\\ \includegraphics[width=.35\textwidth]{radio}& \includegraphics[width=.35\textwidth]{droplist} \end{tabular} \caption{Four basic widgets: a button, a label, radio buttons, and a drop list.} \label{fig:basic-widgets} \end{figure} Now to illustrate (Figure~\ref{fig:basic-widgets} shows a few) some of the basic widgets. These first widgets display text: a label, a button and a text area. First a button: <<>>= obj <- gbutton("Hello world", container = gwindow()) @ Next a label: <<>>= obj <- glabel("Hello world", container = gwindow()) @ Now for single line of editable text: <<>>= obj <- gedit("Hello world", container = gwindow()) @ Finally, a text buffer for multiple lines of text: <<>>= obj <- gtext("Hello world", container = gwindow()) @ The following widgets are used for selection of a value or values from a vector of possible values. First a radio group for selecting just one of several: <<>>= obj <- gradio(c("hello","world"), container=gwindow()) @ Next, combo box, (was called a droplist) again for selecting just one of several, although in this case an option can be give for the user to edit the value. <<>>= obj <- gcombobox(c("hello","world"), container=gwindow()) @ A combo box can also allow its value to be entered by typing, <<>>= obj <- gcombobox(c("hello","world"), editable=TRUE, container=gwindow()) @ For longer lists, a table of values can be used. <<>>= obj <- gtable(c("hello","world"), container=gwindow()) @ This widget is also used for displaying tabular data with multiple columns and rows (data frames). For this widget there is an argument allowing for multiple selections. Multiple selections can also be achieved with a checkbox group: <<>>= obj <- gcheckboxgroup(c("hello","world"), container=gwindow()) @ For selecting a numeric value from a sequence of values, sliders and spinbuttons are commonly used: <<>>= obj <- gslider(from=0, to = 7734, by =100, value=0, container=gwindow()) obj <- gspinbutton(from=0, to = 7734, by =100, value=0, container=gwindow()) @ Common to all of the above is a specification of the ``value'' of the widget, and the container to attach the widget to. In each case a top-level window constructed by \RFunc{gwindow}. \subsection{Using containers} In this next example, we show how to combine widgets together using containers. (Figure~\ref{fig:hello-world}.) <<>>= win <- gwindow("Hello World, ad nauseum", visible=TRUE) group <- ggroup(horizontal = FALSE, container=win) obj <- gbutton("Hello...",container=group, handler = function(h,...) gmessage("world")) obj <- glabel("Hello...", container =group, handler = function(h,...) gmessage("world")) obj <- gcombobox(c("Hello","world"), container=group) obj <- gedit("Hello world", container=group) obj <- gtext("Hello world", container=group, font.attr=list(style="bold")) @ As before, the constructors \RFunc{gbutton}, \RFunc{glabel}, \RFunc{gedit} and \RFunc{gtext} create widgets of different types~\footnote{We refer to \code{gbutton} as a constructor, which it is, and also a widget class, which it technically isn't.}. The button looks like a button. A label is used to show text which may perhaps be edited. [Editing text isn't implemented in all toolkits. and in personal experience seems to be confusing to users.] A combobox allows a user to select one of several items, or as illustrated can take user input. The \RFunc{gedit} and \RFunc{gtext} constructors both create widgets for inputting text, in the first case for single lines, and in the second for multiple lines using a text buffer. \begin{figure}[htbp] \centering \includegraphics[width=.35\textwidth]{hello-world} \caption{Hello world example} \label{fig:hello-world} \end{figure} These widgets are packed into containers (see \code{?ggroup} or \code{?gwindow}). The base container is a window, created with the \RFunc{gwindow} function. A top-level window only contains one widget, like a group, so we pack in a group container created with \RFunc{ggroup}. (Top-level windows also may contain menubars, toolbars and statusbars.) The \RFunc{ggroup} container packs in widgets from left to right or top to bottom. Imagine each widget as a block which is added to the container. In this case, we want the subsequent widgets packed in top to bottom so we used the argument \code{horizontal=FALSE}. For the button and label widgets, a handler is set so that when the widget is clicked a message dialog appears showing ``world.'' Handlers are used to respond to mouse-driven events. In this case the event of a widget being clicked. See \code{?gWidgetsRGtk-handlers} for details on handlers. Note the handler has signature \code{(h,...)} where \code{h} is a list with components \code{obj} referring to the widget the handler is called on, \code{action} referring to the value passed to the \RArg{action} argument and perhaps others (eg. \code{dropdata} for drag-and-drop events, and \code{x} and \code{y} for \code{ggraphics} click events.). The \code{...} in the signature, may contain information passed along by the underlying toolkit and is necessary but not generally employed. The message is an instance of a ``basic dialog'' (see \code{?gWidgets-dialogs}). The dialogs in \code{gWidgets} are modal, meaning R's event loop is stopped until the dialog is answered. (This can be annoying if a dialog appears under another window and can't be seen!) As such, they don't return an object which has methods defined for it, as by the time they can be accessed they have been dismissed. Instead, they return a value like a logical or a string. \section{Making a confirmation dialog} Let's see how we might use widgets to create our own confirmation dialog, one which is not modal. We want to have an icon, a label for the message, and buttons to confirm or dismiss the dialog. The \RFunc{gimage} constructor allows images to be shown in a widget. In \pkg{gWidgetsRGtk} there are several stock images, which can be listed with \RFunc{getStockIcons}. We will use ``info'' below. First we define a function for making a dialog. This one uses nested group containers to organize the layout. (Alternately the \RFunc{glayout} constructor could have been used in some manner.) <<>>= confirmDialog <- function(message, handler=NULL) { window <- gwindow("Confirm") group <- ggroup(container = window) gimage("info", dirname="stock", size="dialog", container=group) ## A group for the message and buttons inner.group <- ggroup(horizontal=FALSE, container = group) glabel(message, container=inner.group, expand=TRUE) ## A group to organize the buttons button.group <- ggroup(container = inner.group) ## Push buttons to right addSpring(button.group) gbutton("ok", handler=handler, container=button.group) gbutton("cancel", handler = function(h,...) dispose(window), container=button.group) return() } @ The key to making a useful confirmation dialog is attaching a response to a click of the ``ok'' button. This is carried out by a handler, which are added using the argument \RArg{handler} for the constructor, or with one of the \code{addHandlerXXX} functions. The handler below prints a message and then closes the dialog. To close the dialog, the \RFunc{dispose} method is called on the ``ok'' button widget, which is referenced inside the handler by \code{h\$obj} below. In \code{gWidgets}, handlers are passed information via the first argument, which is a list with named elements. The \RListel{obj} component refers to the widget the handler is assigned to. Trying it out produces a widget like that shown in Figure~\ref{fig:confirmDialog} \begin{figure}[htbp] \centering \includegraphics[width=.35\textwidth]{confirmDialog} \caption{Confirmation dialog} \label{fig:confirmDialog} \end{figure} <<>>= confirmDialog("This space for rent", handler = function(h,...) { print("what to do... [Change accordingly]") ## In this instance dispose finds its parent window and closes it dispose(h$obj) }) @ %%$ \section{Methods} Widgets are interacted with by their methods. The main methods are \RFunc{svalue} and \RFunc{svalue<-} for getting and setting a widgets primary value. The following silly example illustrates how clicking one widget can be used to update another widget. <<>>= w <- gwindow("Two widgets") g <- ggroup(container = w) widget1 <- gbutton("Click me to update the counter", container=g, handler = function(h,...) { oldVal <- svalue(widget2) svalue(widget2) <- as.numeric(oldVal) + 1 }) widget2 <- glabel(0, container=g) @ The value stored in a label is just the text of the label. This is returned by \RFunc{svalue} and after 1 is added to the value, replaced back into the label. As text labels are of class ``character,'' the value is coerced to be numeric. There are other methods (see \code{?gWidgetsRGtk-methods}) that try to make interacting with a widget as natural (to an R user) as possible. For instance, a radio button has a selected value returned by \RFunc{svalue}, but also a vector of possible values. These may be referenced using vector, \code{[}, notation. Whereas, a notebook container has a \RFunc{names} method which refers to the tab labels, which may be set via \code{names<-} and a \RFunc{length} method to return the number of notebook pages. \section{Adding a GUI to some common tasks} A GUI can make some command line tasks easier to perform. Here are a few examples that don't involve much coding in \code{gWidgets}. \subsection{\RFunc{file.choose}} The \RFunc{file.choose} function is great for simplifying a user's choice of a file from the file system. A typical usage might be \begin{Soutput} source(file.choose()) \end{Soutput} to allow a user to source a file with a little help from a GUI. However, in many UNIX environments, there is no GUI for \RFunc{file.choose}, only a more convenient curses interface. With the \RFunc{gfile} dialog, we can offer some improvement. This dialog returns the name of the file selected, so that \begin{Soutput} source(gfile()) \end{Soutput} can replace the above. More in keeping with the \code{gWidgets} style, though, would be to give a handler when constructing the file chooser. The \code{file} component of the handler argument gives the files name (not \code{svalue(h\$obj)}, as \code{gfile} does not return an object to call \code{svalue} on). For example, the function below is written to give some flexibility to the process: %%$ <<>>= fileChoose <- function(action="print", text = "Select a file...", type="open", ...) { gfile(text=text, type=type, ..., action = action, handler = function(h,...) { do.call(h$action, list(h$file)) }) } @ The \RArg{action} argument parametrizes the action. The default above calls \RFunc{print} on the selected file name, hence printing the name. However, other tasks can now be done quite simply. For example, to \RFunc{source} a file we have: %% not in <<>>=/@ as they are modal and mess up Sweave \begin{Sinput} > fileChoose(action="source") \end{Sinput} Or to set the current working directory we have: \begin{Sinput} > fileChoose(action="setwd", type="selectdir", text="Select a directory...") \end{Sinput} \subsection{\RFunc{browseEnv}} \label{sec:browseEnv} The \RFunc{browseEnv} function creates a table in a web browser listing the current objects in the global environment (by default) and details some properties of them. This is an easy to use function, but suffers from the fact that it may have to open up a browser for the user if none is already open. This may take a bit of time as browsers are generally slow to load. We illustrate a means of using the \RFunc{gtable} constructor to show in a table the objects in an environment. The following function creates the data.frame we will display. Consult the code of \RFunc{browseEnv} to see how to produce more details. <<>>= lstObjects <- function(envir= .GlobalEnv, pattern) { objlist <- ls(envir=envir, pattern=pattern) objclass <- sapply(objlist, function(objName) { obj <- get(objName, envir=envir) class(obj)[1] }) data.frame(Name = I(objlist), Class = I(objclass)) } @ Now to make a table to display the results. We have some flexibility with the arguments, which is shown in subsequent examples: <<>>= browseEnv1 <- function(envir = .GlobalEnv, pattern) { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv1")) } @ Tables can have a double click handler (typically a single click is used for selection). To illustrate, we add a handler which calls \RFunc{summary} (or some other function) on a double-clicked item [Qt's behaviour is OS dependent]. (The first \code{svalue} returns a character string, it is promoted to an object using \code{get}) <<>>= browseEnv2 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv2"), action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } @ As a final refinement, we add a combobox to filter by the unique values of ``Class.'' We leave as an exercise the display of icons based on the class of the object. <<>>= browseEnv3 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container =gwindow("browseEnv3"), filter.column = 2, action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } @ [The \code{filter} argument is not available with \pkg{gWidgetsrJava} or \pkg{gWidgetsWWW}.] In \pkg{gwidgetsRGtk2} The \RFunc{gvarbrowser} function constructs a widget very similar to this, only it uses a \RFunc{gtree} widget to allow further display of list-like objects. [The \code{gtree} widget is not implemented in all of the toolkits.] \section{A gWidgetsDensity demo} \label{sec:repeating-plot} We illustrate how to make a widget dynamically update a density plot. The idea comes from the \code{tkdensity} demo that accompanies the \pkg{tcltk} package due to, I believe, Martin Maechler. We use the \RFunc{ggraphics} constructor to create a new plot device. For RGtk2, this uses the \pkg{cairoDevice} package also developed by Michael Lawrence. (This package takes some work to get going under OS X, as the easy-to-install RGtk2 libraries don't seem to like the package.) [In \pkg{gWidgetsrJava} the \pkg{JavaGD} package is used for a JAVA device. In theory this should be embeddable in a \pkg{gWidgets} container, but it isn't implemented, so a new window is created.] [In \pkg{gWidgetstcltk} there is no embeddable graphics device. (The \pkg{tkrplot} is different.) The \code{ggraphics} call would just put in a stub.] This demo consists of a widget to control a random sample, in this case from the standard normal distribution or the exponential distribution with rate 1; a widget to select the sample size; a widget to select the kernel; and a widget to adjust the default bandwidth. We use radio buttons for the first two, a drop list for the third and a slider for the latter. The \pkg{gWidgetstcltk} package is a little different from the other two, as it requires that a container be non-null. This is because the underlying \pkg{tcltk} widgets need to have a parent container to be initialized. As such, the following won't work. A working example will be given next for comparison. This one is left here, as the separation of GUI building into: widget definition; widget layout; and assignment of handlers, or call backs, seems to lead to easier to understand code. Proceeding, first we define the two distributions and the possible kernels. <>= ## set up availDists <- c(Normal="rnorm", Exponential="rexp") availKernels <- c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine") @ We then define the key function for drawing the graphic. This refers to widgets yet to be defined. <>= updatePlot <- function(h,...) { x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) plot(density(x, adjust = svalue(bandwidthAdjust), kernel = svalue(kernel)),main="Density plot") rug(x) } @ Now to define the widgets. <>= distribution <- gradio(names(availDists), horizontal=FALSE, handler=updatePlot) kernel <- gcombobox(availKernels, handler=updatePlot) bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, handler=updatePlot) sampleSize <- gradio(c(50,100,200, 300), handler = updatePlot) @ Now the layout. We use frames to set off the different arguments. A frame is like a group, only it has an option for placing a text label somewhere along the top. The position is specified via the \code{pos} argument, with a default using the left-hand side. <>= ## now layout window <- gwindow("gWidgetsDensity") BigGroup <- ggroup(cont=window) group <- ggroup(horizontal=FALSE, container=BigGroup) tmp <- gframe("Distribution", container=group) add(tmp, distribution) tmp <- gframe("Sample size", container=group) add(tmp,sampleSize) tmp <- gframe("Kernel", container=group) add(tmp,kernel) tmp <- gframe("Bandwidth adjust", container=group) add(tmp,bandwidthAdjust, expand=TRUE) @ Now to add a graphics device. <>= add(BigGroup, ggraphics()) @ [Again, if using \RFunc{gWidgetsrJava} this wouldn't place the device inside the \code{BigGroup} container.] A realization of this widget was captured in Figure~\ref{fig:gtkdensity}. \begin{figure} \centering \includegraphics[width=.6\textwidth]{gtkdensity} \caption{The gWidgetsDensity example in action.} \label{fig:gtkdensity} \end{figure} Now, as promised, we present a function that would work under any of the toolkits. The \code{ggraphics} call is not included, as this doesn't work with \pkg{gWidgetstcltk}. The key difference though is the containers are included in the creation of the widgets. The arguments that would be passed to \code{add} are included in the construction of the widget. <>= gwtkdensity <- function() { ## set up availDists <- c(Normal = "rnorm", Exponential="rexp") availKernels <- c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine") updatePlot <- function(h,...) { x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) plot(density(x, adjust = svalue(bandwidthAdjust), kernel = svalue(kernel))) rug(x) } ##The widgets win <- gwindow("gwtkdensity") gp <- ggroup(horizontal=FALSE, cont=win) tmp <- gframe("Distribution", container=gp, expand=TRUE) distribution <- gradio(names(availDists), horizontal=FALSE, cont=tmp, handler=updatePlot) tmp <- gframe("Sample size", container=gp, expand=TRUE) sampleSize <- gradio(c(50,100,200, 300), cont=tmp, handler =updatePlot) tmp <- gframe("Kernel", container=gp, expand=TRUE) kernel <- gcombobox(availKernels, cont=tmp, handler=updatePlot) tmp <- gframe("Bandwidth adjust", container=gp, expand=TRUE) bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, cont=tmp, expand=TRUE, handler=updatePlot) } @ \section{Composing email} This example shows how to write a widget for composing an email message. Not that this is what R is intended for, but rather to show how a familiar widget is produced by combining various pieces from \code{gWidgets}. This example is a little lengthy, but hopefully straightforward due to the familiarity with the result of the task. For our stripped-down compose window we want the following: a menubar to organize functions; a toolbar for a few common functions; a ``To:'' field which should have some means to store previously used e-mail addresses; a ``From:'' field that should be editable, but not obviously so as often it isn't edited; a ``Subject:'' field which also updates the title of the window; and a text buffer for typing the message. The following code will create a function called \RFunc{Rmail} (apologies to any old-time emacs users) which on many UNIX machines can send out e-mails using the \code{sendmail} command. This is not written to work with \code{gWidgetstcltk}. First we define some variables: <>= FROM <- "gWidgetsRGtk " buddyList <- c("My Friend ","My dog ") @ Now for the main function. We define some helper functions inside the body, so as not to worry about scoping issues. <>= Rmail <- function(draft = NULL, ...) { ## We use a global list to contain our widgets widgets <- list() ## Helper functions sendIt <- function(...) { tmp <- tempfile() cat("To:", svalue(widgets$to),"\n",file = tmp, append=TRUE) cat("From:", svalue(widgets$from),"\n", file=tmp, append=TRUE) cat("Subject:", svalue(widgets$subject),"\n", file=tmp, append=TRUE) cat("Date:", format(Sys.time(),"%d %b %Y %T %Z"),"\n", file=tmp, append=TRUE) cat("X-sender:", "R", file=tmp, append=TRUE) cat("\n\n", file=tmp, append=TRUE) cat(svalue(widgets$text), file=tmp, append=TRUE) cat("\n", file=tmp, append=TRUE) ## Use UNIX sendmail to send message system(paste("sendmail -t <", tmp)) ## Add To: to buddyList if(exists("buddyList")) assign("buddyList", unique(c(buddyList,svalue(widgets$to))), inherits=TRUE) ## Close window, delete file unlink(tmp) dispose(window) } ## Function to save a draft to the file draft.R saveDraft <- function(...) { draft <- list() sapply(c("to","from","subject","text"), function(i) draft[[i]] <<- svalue(widgets[[i]]) ) dump("draft","draft.R") cat("Draft dumped to draft.R\n") } ## A simple dialog aboutMail <- function(...) gmessage("Sends a message") ## Make main window from top down window <- gwindow("Compose mail", visible=FALSE) group <- ggroup(horizontal=FALSE, spacing=0, container = window) ## Remove border svalue(group) <- 0 actions <- list(save=gaction("Save", icon="save", handler=saveDraft), send=gaction("Send", icon="connect", handler=sendIt), quit=gaction("Quit", icon="quit", handler=function(...) dispose(window)), about=gaction("About", icon="about", handler=aboutMail)) ## Menubar is defined by the actions, but we nest under File menu menubarlist <- list(File=actions) gmenu(menubarlist, cont = window) ## Toolbar is also defined by the actions toolbarlist <- actions[-4] gtoolbar(toolbarlist, cont=window) ## Put headers in a glayout() container tbl <- glayout(container = group) ## To: field. Looks for buddyList tbl[1,1] <- glabel("To:", container = tbl) tbl[1,2] <- (widgets$to <- gcombobox(c(""), editable=TRUE, container=tbl, expand=TRUE)) size(widgets$to) <- c(300, -1) if(exists("buddyList")) widgets$to[] <- buddyList ## From: field. Click to edit value tbl[2,1] <- glabel("From:", container = tbl) tbl[2,2] <- (widgets$from <- glabel(FROM, editable=TRUE, container=tbl)) ## Subject: field. Handler updates window title tbl[3,1] <- glabel("Subject:", container=tbl) tbl[3,2] <- (widgets$subject <- gedit("",container=tbl)) addHandlerKeystroke(widgets$subject, handler = function(h,...) svalue(window) <- paste("Compose mail:",svalue(h$obj),collapse="")) ## Add text box for message, but first some space addSpace(group, 5) widgets$text <- gtext("", container = group, expand=TRUE) ## Handle drafts. Either a list or a filename to source") ## The generic svalue() method makes setting values easy") if(!is.null(draft)) { if(is.character(draft)) sys.source(draft,envir=environment()) # source into right enviro if(is.list(draft)) { sapply(c("to","from","subject","text"), function(i) { svalue(widgets[[i]]) <- draft[[i]] }) } } visible(window) <- TRUE ## That's it. } @ %%$ To compose an e-mail we call the function as follows. (The widget constructed looks like Figure~\ref{fig:Rmail}.) <>= Rmail() @ \begin{figure}[htbp] \centering \includegraphics[width=.5\textwidth]{Rmail} \caption{Widget for composing an e-mail message. (Needs a grammar checker.) } \label{fig:Rmail} \end{figure} The \RFunc{Rmail} function uses a few tricks. A combobox is used to hold the ``To:'' field. This is done so that a ``buddy list'' can be added if present. The \code{[<-} method for comboboxes make this straightforward. For widgets that have a collection of items to select from, the vector and matrix methods are defined to make changing values familiar to R users. (Although the use of the method \code{[<-} for \code{glayout} containers can cause confusion, as no \code{[} method exists due to the indexing referring to coordinates and not indexes.) The ``From:'' field uses an editable label. Clicking in the label's text allows its value to be changed. Just hit ENTER when done.~\footnote{Editable labels seemed like a good idea at the time -- they were borrowed from gmail's interface -- but in experience they seem to be confusing to users. YMMV.} The handler assigned to the ``Subject:'' field updates the window title every keystroke. The title of the window is updated with the windows \RFunc{svalue<-} method. The \RFunc{svalue} and \RFunc{svalue<-} methods are the work-horse methods of \code{gWidgets}. The are used to retrieve the selected value of a widget or set the selected value of a widget. One advantage to have a single generic function do this is illustrated in the handling of a draft: \begin{Soutput} sapply(c("to","from","subject","text"), function(i) svalue(widgets[[i]]) <- draft[[i]]) \end{Soutput} (Another work-horse method is \RFunc{addHandlerChanged} which can be used to add a handler to any widget, where ``changed'' -- being a generic function -- is loosely interpreted: i.e., for buttons, it is aliased to \RFunc{addHandlerClicked}. As for the \RFunc{sendIt} function, this is just one way to send an e-mail message on a UNIX machine. There are likely more than 100 different ways clever people could think of doing this task, most better than this one. To make portable code, when filling in the layout container, the widget constructors use the layout container as the parent container for the new widget. \section{An expanding group} As an example of the \code{add} and \code{delete} methods of a container, we show how one could create the \code{gexpandgroup} widget, were it not implemented by the underlying toolkit (eg. \pkg{gWidgetstcltk}). This container involves an icon to click on to show the container and a similar icon to hide the container. A label indicates to the user what is going on. <>= ## expand group rightArrow <- system.file("images/1rightarrow.gif",package="gWidgets") downArrow <- system.file("images/1downarrow.gif",package="gWidgets") g <- ggroup(horizontal=FALSE,cont=T) g1 <- ggroup(horizontal=TRUE, cont=g) icon <- gimage(downArrow,cont=g1) label <- glabel("Expand group example", cont=g1) g2 <- ggroup(cont=g, expand=TRUE) expandGroup <- function() add(g,g2, expand=TRUE) hideGroup <- function() delete(g,g2) state <- TRUE # a global changeState <- function(h,...) { if(state) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } state <<- !state } addHandlerClicked(icon, handler=changeState) addHandlerClicked(label, handler=changeState) gbutton("Hide by clicking arrow", cont=g2) @ %%>> As an alternative to using the global \code{state} variable, the \RFunc{tag} function could be used. This is like \RFunc{attr} only it stores the value with the widget -- not a copy -- so can be used within a handler to propogate changes outside the scope of the handler call. For instance, the \code{changeState} function could have been written as <<>>= tag(g,"state") <- TRUE # a global changeState <- function(h,...) { if(tag(g,"state")) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } tag(g,"state") <- !tag(g,"state") } @ Other alternatives to using global variables include using environments or the \pkg{proto} package for \code{proto} objects. These objects are passed not by copy, but by reference so changes within a function are reflected outside the scope of the function. \section{Drag and drop} GTK supports drag and drop features, and the \code{gWidgets} API provides a simple mechanism to add drag and drop to widgets. (Some widgets, such as text boxes, support drag and drop without these in GTK.) The basic approach is to add a drop source to the widget you wish to drag from, and add a drop target to the widget you want to drag to. You can also provide a handler to deal with motions over the drop target. See the man page \code{?gWidgetsRGtk-dnd} for more information. [In \pkg{gWidgetsQt} drag and drop support is very limited.] [In \pkg{gWidgetsrJava} drag and drop is provided through Java and not \pkg{gWidgets}. One can drag from widget to widget, but there is no way to configure what happens when a drop is made, or what is dragged when a drag is initiated.] [In \pkg{gWidgetstcltk} drag and drop works but not from other applications. ] We give two examples of drag and drop. One where variables from the variable browser are dropped onto a graph widget. Another illustrating drag and drop from the data frame editor to a widget. \subsection{DND with plots} This example shows the use of the plot device, the variable browser widget, and the use of the drag and drop features of gWidgets (Figure~\ref{fig:doPlot}). <<>>= doPlot <- function() { ## Set up main group mainGroup <- ggroup(container=gwindow("doPlot example")) ## The variable browser widget gvarbrowser(container = mainGroup) rightGroup <- ggroup(horizontal=FALSE, container=mainGroup) ## The graphics device ggraphics(container=rightGroup) entry <- gedit("drop item here to be plotted", container=rightGroup) adddroptarget(entry,handler = function(h,...) { do.call("plot",list(svalue(h$dropdata),main=id(h$dropdata))) }) } @ %%$ <>= doPlot() @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{doPlot.png} \caption{Dialog produced by \RFunc{doPlot} example} \label{fig:doPlot} \end{figure} The basic structure of using \code{gWidgets} is present in this example. The key widgets are the variable browser (\RFunc{gvarbrowser}), the plot device (\RFunc{ggraphics}), and the text-entry widget (\RFunc{gedit}). (One can see an \pkg{RGtk2} bias here, as the other implementations do not currently have an embeddable graphics device.) These are put into differing containers. Finally, there is an handler given to the result of the drag and drop. The \RFunc{do.call} line uses the \RFunc{svalue} and \RFunc{id} methods on a character, which in this instance returns the variable with that name and the name. To use this widget, one drags a variable to be plotted from the variable browser over to the area below the plot window. The \RFunc{plot} method is called on the values in the dropped variable. The \code{gvarbrowser} produces a widget from which a drop \textit{source} has been added. To drop from a different source the \code{addDropSource} method is used. The return value of the handler will be passed to the \code{dropdata} value of the handler for \code{addDropTarget}. [The latter varies from toolkit to toolkit, in \pkg{gWidgetsrJava} both are ignored, in RGtk2 some widgets have built-in drag and drop which can be overridden, and in \pkg{gWidgetstcltk} everything must be done using the \pkg{gWidgets} interface, as drag and drop is not naturally implemented by the toolkit.] %% \subsection{DND from the data frame editor} %% [This example applies only to \pkg{gWidgetsRGtk}, not %% \pkg{gWidgetsrJava} or \pkg{gWidgetstcltk}] %% The \RFunc{gdf} constructor makes a widget for editing data %% frames. The columns of which can be dropped onto a widget. This is %% done by dragging the column header. The code below also adds a handler %% so that changes to the column propagate to changes in the widget where %% the column is dropped. (Careful, this has some issues: the handler needs to %% be removed if the widget is closed.) %% <<>>= %% ## Drag a column onto plot to have a boxplot drawn. %% ## Changing the column values will redraw the graph. %% makeDynamicWidget <- function() { %% win <- gwindow("Draw a boxplot") %% gd <- ggraphics(container = win) %% adddroptarget(gd, targetType="object", handler=function(h,...) { %% tag(gd,"data") <- h$dropdata %% plotWidget(gd) %% ## this makes the dynamic part: %% ## - we put a change handler of the column that we get the data from %% ## - we store the handler id, so that we can clean up the handler when this %% ## window is closed %% ## The is.gdataframecolumn function checks if the drop value %% ## comes from the data frame editor (gdf) %% if(gWidgetsRGtk2:::is.gdataframecolumn(h$dropdata)) { %% view.col <- h$dropdata %% ## Put change handler on column to update plotting widget %% ## (use lower case, to fix oversight) %% id <- addhandlerchanged(view.col, handler=function(h,...) plotWidget(gd)) %% ## Save drop handler id so that it can be removed when %% ## widget is closed %% dropHandlers <- tag(gd,"dropHandlers") %% dropHandlers[[length(dropHandlers)+1]] <- %% list(view.col = view.col, %% id = id %% ) %% tag(gd,"dropHandlers") <- dropHandlers %% } %% }) %% ## Remove drop handlers if widget is unrealized. %% addHandlerUnrealize(gd, handler = function(h,...) { %% dropHandlers <- tag(gd,"dropHandlers") %% if(length(dropHandlers) > 0) { %% for(i in 1:length(dropHandlers)) { %% removehandler(dropHandlers[[i]]$view.col,dropHandlers[[i]]$id) %% } %% } %% }) %% } %% @ %% %% $ %% Next, we make the function that produces or updates the graphic. The %% data is stored in the tag-key "data". The use of \RFunc{id} and %% \RFunc{svalue} works for values which are either variable names or columns. %% <>= %% plotWidget <- function(widget) { %% data <- tag(widget, "data") %% theName <- id(data) %% values <- svalue(data) %% boxplot(values, xlab=theName, horizontal=TRUE, col=gray(.75)) %% } %% @ %% Now show the two widgets, the \RFunc{gdf} function constructs the data %% frame editor widget. %% <>= %% gdf(mtcars, container=TRUE) %% makeDynamicWidget() %% @ %% %%$ \section{Notebooks} The notebook is a common metaphor with computer applications, as they can give access to lots of information compactly on the screen. The \RFunc{gnotebook} constructor produces a notebook widget. New pages are added via the \RFunc{add} method (which is called behind the scenes when a widget is constructed), the current page is deleted through an icon [not implemented in \pkg{gWidgetsrJava}], or via the \RFunc{dispose} method, and vector methods are defined, such as \RFunc{names}, to make interacting with notebooks natural (the names refer to the tab labels.) One can also add pages when constructing a widget using the notebook as the container and passing in an extra argument \code{label}. The following example shows how a notebook can be used to organize different graphics devices. [In \pkg{gWidgetsRGtk2} the \RFunc{ggraphicsnotebook} function produces a similar widget. However, this is not possible if using \pkg{gWidgetsrJava}, as the graphic devices can't currently be embedded in a notebook page.] Our widget consists of a toolbar to add or delete plots and a notebook to hold the different graphics devices. The basic widgets are defined by the following: First we make window and group containers to hold our widgets and then a notebook instance. <<>>= win <- gwindow("Plot notebook") group <- ggroup(horizontal = FALSE, container=win) nb <- gnotebook(container = group, expand=TRUE) @ (\code{expand=TRUE} causes the child widget -- the notebook -- to expand to take as much space as allotted.) Next, we begin with an initial plot device. \begin{Soutput} > ggraphics(container = nb, label="plot") \end{Soutput} The \code{label} argument goes on the tab, as it is passed to the notebook's \code{add} method. Now we define and add a toolbar. <<>>= tblist <- list(quit=gaction("Quit", icon="quit", handler=function(...) dispose(win)), separator=gseparator(), new=gaction("New", icon="new", handler=function(h,...) add(nb,ggraphics(),label="plot")), delete=gaction("Delete", icond="delete", handler=function(...) dispose(nb)) ) gtoolbar(tblist, cont=group) @ The \RFunc{dispose} method is used both to close the window, and to close a tab on the notebook (the currently selected one). \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{notebook} \caption{Notebook widget for holding multiple plot devices provided by \RFunc{ggraphics}} \label{fig:notebook} \end{figure} That's it (Figure~\ref{fig:notebook}). There is one thing that should be added. If you switch tabs, the active device does not switch. This happens though if you click in the plot area. To remedy this, you can think about the \RFunc{addHandlerChanged} method for the notebook, or just use \RFunc{ggraphicsnotebook}. \section{The tree widget} The \RFunc{gtree} constructor [this widget is only implemented in \pkg{gWidgetsRGtk2}.] is used to present tree-like data. A familiar example of such data is the directory structure of your computer. To display a tree, \RFunc{gtree} needs to know what to display (the offspring) and which offspring have further offspring. idea of a node which consists of a path back to a root node. The offspring are determined by a function (\RFunc{offspring}) which takes the current path (ancestor information), and a passed in parameter as arguments. These offspring can either have subsequent offspring or not. This information must be known at the time of displaying the current offspring, and is answered by a function (\RFunc{hasOffspring}) which takes as an argument the offspring. In our file-system analogy, \RFunc{offspring} would list the files and directories in a given directory, and \RFunc{hasOffspring} would be \code{TRUE} for a directory in this listing, and \code{FALSE} for a file. For decorations, a function \RFunc{icon.FUN} can be given to decide what icon to draw for which listing. This should give a stock icon name. The data presented for the offspring is a data frame, with one column determining the path. This is typically the first column, but can be set with \RArg{chosencol}. \\ To illustrate, we create a file system browser using \RFunc{gtree}. (This is for UNIX systems. change the file separator for windows.) First to define the \RFunc{offspring} function we use the \RFunc{file.info} function. The current working directory is used as the base node for the tree: <<>>= ## function to find offspring offspring <- function(path, user.data=NULL) { if(length(path) > 0) directory <- paste(getwd(),"/",paste(path,sep="/", collapse=""),sep="",collapse="") else directory <- getwd() tmp <- file.info(dir(path=directory)) files <- data.frame(Name=rownames(tmp), isdir=tmp[,2], size=as.integer(tmp[,1])) return(files) } @ The offspring function is determined by the \code{isdir} column in the offspring data frame. <<>>= hasOffspring <- function(children,user.data=NULL, ...) { return(children$isdir) } @ Finally, an icon function can be given as follows, again using the \code{isdir} column. <<>>= icon.FUN <- function(children,user.data=NULL, ...) { x <- rep("file",length= nrow(children)) x[children$isdir] <- "directory" return(x) } @ The widget is then constructed as follows. See Figure~\ref{fig:filebrowser} for an example. <<>>= gtree(offspring, hasOffspring, icon.FUN = icon.FUN, container=gwindow(getwd())) @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{filebrowser} \caption{Illustration of a file browser using \RFunc{gtree} constructor.} \label{fig:filebrowser} \end{figure} The presence of the \code{isdir} column may bug some. It was convenient when defining \RFunc{hasOffspring} and \RFunc{icon.FUN}, but by then had served its purpose. One way to eliminate it, is to use the default for the \RArg{hasOffspring} argument which is to look for the second column of the data frame produced by \RFunc{offspring}. If this column is of class \code{logical}, it is used to define \RFunc{hasOffspring} and is then eliminated from the display. That is, the following would produce the desired file browser: <<>>= gtree(offspring, icon.FUN = icon.FUN, container=gwindow(getwd())) @ Finally, the \RArg{handler} argument (or \code{addHandlerDoubleclick}) could have been used to give an action to double clicking of an item in the tree. \section{Popup menus} A popup menu ``pops'' up a menu after a mouse click, typically a right mouse click. Implemented in \pkg{gWidgets} are the functions \begin{description} \item[\RFunc{add3rdmousepopupmenu}] for adding a popup on a right click \item[\RFunc{addpopupmenu}] for adding a popup on any click \end{description} The menu is specified using the syntax for \RFunc{gmenu}. \\ A simple example would be something like: <<>>= w <- gwindow("Click on button to change") g <- ggroup(cont = w) # abbreviate container glabel("Hello ", cont=g) world <- gbutton("world", cont=g) lst <- list() lst$world$handler <- function(h,...) svalue(world) <- "world" lst$continent$handler <- function(h,...) svalue(world) <- "continent" lst$country$handler <- function(h,...) svalue(world) <- "country" lst$state$handler <- function(h,...) svalue(world) <- "state" addPopupmenu(world, lst) @ Clicking on ``world'' with the mouse allows one to change the value in the label. \section{Defining layouts with \RFunc{gformlayout}} The \RFunc{gformlayout} constructor allows one to define the layout of a GUI using a list. The details of the list are in the man page, but the list has a relatively simple structure. Each widget is specified using a list. The widget type is specified through the \code{type} component as a string. These may be containers or widgets or the special container \code{fieldset}. For containers, the component \code{children} is used to specify the children to pack in. These again are specified using a list, and except for the \code{fieldset} container may again contain containers. The \code{name} argument is used to have the newly created component stored in a list of widgets for later manipulations. There are means to control whether a component is enabled or not based on a previously defined component, such as a checkbox. (This works much better under \pkg{gWidgetsRGtk2} than \pkg{gWidgetstcltk} as disabled parent containers do not disable their children in the latter.) This example comes from the man page. It shows how the ``fieldset'' container is used with some of its arguments to modify the number of columns and adjust the default label placements. We present the final list, \code{tTest} using some predefined lists that could be recycled for other GUIs if desired. <>= ## layout a collection of widgets to generate a t.test ## widgets to gather the variable(s) varList <- list(type="fieldset", columns = 2, label = "Variable(s)", label.pos = "top", label.font = c(weight="bold"), children = list( list(name = "x", label = "x", type = "gedit", text = ""), list(name = "y", label = "y", type = "gedit", text = "", depends.on = "x", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur" ) ) ) ## list for alternative altList <- list(type = "fieldset", label = "Hypotheses", columns = 2, children = list( list(name = "mu", type = "gedit", label = "Ho: mu=", text = "0", coerce.with = as.numeric), list(name = "alternative", type="gcombobox", label = "HA: ", items = c("two.sided","less","greater") ) ) ) ## now make t-test list tTest <- list(type = "ggroup", horizontal = FALSE, children = list( varList, altList, list(type = "fieldset", label = "two sample test", columns = 2, depends.on = "y", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur", children = list( list(name = "paired", label = "paired samples", type = "gcombobox", items = c(FALSE, TRUE) ), list(name = "var.equal", label = "assume equal var", type = "gcombobox", items = c(FALSE, TRUE) ) ) ), list(type = "fieldset", columns = 1, children = list( list(name = "conf.level", label = "confidence level", type = "gedit", text = "0.95", coerce.with = as.numeric) ) ) ) ) @ <>= ## Code to call the layout w <- gwindow("t.test") g <- ggroup(horizontal = FALSE, cont = w) fl <- gformlayout(tTest, cont = g, expand=TRUE) bg <- ggroup(cont = g) addSpring(bg) b <- gbutton("run t.test", cont = bg) addHandlerChanged(b, function(h,...) { out <- svalue(fl) out$x <- svalue(out$x) # turn text into numbers if(out$y == "") { out$y <- out$paired <- NULL } else { out$y <- svalue(out$y) } ## easy, not pretty print(do.call("t.test",out)) }) @ \section{Making widgets from an R function} A common task envisioned for \pkg{gWidgets} is to create GUIs that make collecting the arguments to a function easier to remember or enter. Presented below are two ways to do so without having to do any programming, provided you are content with the layout and features provided. \subsection{Using \RFunc{ggenericwidget}} \label{sec:using-ggenericwidget} The \RFunc{ggenericwidget} constructor maps a list into a widget. The list contains two types of information: meta information about the widget, such as the name of the function, and information about the widgets. This is specified using a list whose first component is the constructor, and subsequent components are fed to the constructor. To illustrate, a GUI for a one sample t-test is given. The list used by \RFunc{ggenericwidget} is defined below. <<>>= lst <- list() lst$title <- "t.test()" lst$help <- "t.test" lst$variableTypes <- "univariate" lst$action <- list(beginning="t.test(",ending=")") lst$arguments$hypotheses$mu <- list(type = "gedit",text=0,coerce.with=as.numeric) lst$arguments$hypotheses$alternative <- list(type="gradio", items=c("'two.sided'","'less'","'greater'") ) @ This list is then given to the constructor. <>= ggenericwidget(lst, container=gwindow("One sample t test")) @ Although this looks intimidating, due to the creation of the list, there is a function \RFunc{autogenerategeneric} that reduces the work involved. In particular, if the argument to \RFunc{ggenericwidget} is a character, then it is assumed to be the name of a function. From the arguments of this function, a layout is guessed. %% For example, we could have done: %% <>= %% our.t.test <- stats:::t.test.default %% ggenericwidget("our.t.test", container=gwindow("t-test")) %% @ %% As the arguments of this function are given by \code{args(out.t.test)} %% This widget has fields for selecting the alternative, the null, %% whether the data is paired, has equal variance assumption and a field %% to adjust the confidence level. \subsection{An alternative to \RFunc{ggenericwidget}} \label{sec:an-altern-ggenericwidget} This next example shows a different (although ultimately similar) way to produce a widget for a function. One of the points of this example is to illustrate the power of having common method names for the different widgets. Of course, the following can be improved. Two obvious places are the layout of the automagically generated widget, and and the handling of the initial variable when a formula is expected. <<>>= ## A constructor to automagically make a GUI for a function gfunction <- function(f, window = gwindow(title=fName), ...) { ## Get the function and its name if(is.character(f)) { fName <- f f <- get(f) } else if(is.function(f)) { fName <- deparse(substitute(f)) } ## Use formals() to define the widget lst <- formals(f) ## Hack to figure out variable type type <- NULL if(names(lst)[1] == "x" && names(lst)[2] == "y") { type <- "bivariate" } else if(names(lst)[1] == "x") { type <- "univariate" } else if(names(lst)[1] == "formula") { type <- "model" } else { type + NULL } ## Layout w <- gwindow("create dialog") g <- ggroup(horizontal = TRUE, cont=w) ## Arrange widgets with an output area ## Put widgets into a layout container tbl <- glayout(container=g) gseparator(horizontal=FALSE, container=g) outputArea <- gtext(container=g, expand=TRUE) ## Make widgets for arguments from formals() widgets <- sapply(lst, getWidget, cont=tbl) ## Layout widgets for( i in 1:length(widgets)) { tbl[i,1] <- names(lst)[i] tbl[i,2] <- widgets[[i]] } ## Add update handler to each widget when changed sapply(widgets, function(obj) { try(addHandlerChanged(obj, function(h,...) update()), silent=TRUE) }) ## Add drop target to each widget sapply(widgets, function(obj) try(adddroptarget(obj, handler=function(h,...) { svalue(h$obj) <- h$dropdata update() }), silent=TRUE)) ## In case this doesn't get exported svalue.default <- function(obj, ...) obj ## Function used to weed out 'NULL' values to widgets isNULL <- function(x) ifelse(class(x) == "character" && length(x) ==1 && x == "NULL", TRUE, FALSE) ## Function called when a widget is changed ## 2nd and 3rd lines trim out non-entries update <- function(...) { is.empty <- function(x) return(is.na(x) || is.null(x) || x == "" ) outList <- lapply(widgets,svalue) outList <- outList[!sapply(outList,is.empty)] outList <- outList[!sapply(outList,isNULL)] outList[[1]] <- svalue(outList[[1]]) if(type == "bivariate") outList[[2]] <- svalue(outList[[2]]) out <- capture.output(do.call(fName,outList)) dispose(outputArea) if(length(out)>0) add(outputArea, out) } invisible(NULL) } @ The \RFunc{getWidget} function takes a value from \RFunc{formals} and maps it to an appropriate widget. For arguments of type \code{call} the function recurses. <<>>= getWidget <- function(x, cont=cont) { switch(class(x), "numeric" = gedit(x, coerce.with=as.numeric, cont=cont), "character" = gcombobox(x, active=1, cont=cont), "logical" = gcombobox(c(TRUE,FALSE), active = 1 + (x == FALSE), cont=cont), "name" = gedit("", cont=cont), "NULL" = gedit("NULL", cont=cont), "call" = getWidget(eval(x), cont=cont), # recurse gedit("", cont=cont) # default ) } @ %% not there "list" = gListOfWidgets(x,name="", cont=cont), % This function defines a separate widget to handle the case where an % argument expects a list. It is written in the \code{gWidgetsRGtk} style % including an \RFunc{svalue} method below. The \RFunc{tag} method stores % a value in the widget, similar to setting an attribute. In this case, % the list of widgets stored is consulted by the following \RFunc{svalue} method. % <<>>= % gListOfWidgets = function(lst, name = "", container=NULL, ...) { % gp = gframe(text = name, container=container, horizontal=FALSE, ...) % obj = list(ref=gp) % class(obj) = c("gListOfWidgets") % tbl = glayout(container = gp) % widgetList = lapply(lst, getWidget, cont=tbl) % tag(obj, "widgetList") <- widgetList % ## pack into layout % for(i in 1:length(widgetList)) { % tbl[i,1] = names(widgetList)[i] % tbl[i,2] = widgetList[[i]] % } % visible(tbl) <- TRUE % return(obj) % } % @ % The methods below (\RFunc{svalue}, \RFunc{svalue<-} and % \RFunc{addHandlerChanged}) map the same method to each component % of the list using \RFunc{sapply}. % <<>>= % svalue.gListOfWidgets = function(obj, ...) { % lst = lapply(tag(obj, "widgetList"), svalue) % return(lst) % } % "svalue<-.gListOfWidgets" = function(obj, ..., value) { % if(!is.list(value)) % return(obj) % widgetList = getdata(obj, "widgetList") % sapply(names(value), function(x) svalue(widgetList[[x]]) <- value[[x]]) % return(obj) % } % addHandlerChanged.gListOfWidgets = function(obj, handler=NULL, action=NULL, ...) { % widgetList = getdata(obj, "widgetList") % sapply(widgetList, function(x) % try(addHandlerChanged(x, handler, action),silent=TRUE)) % } % @ We can try this out on the default \RFunc{t.test} function. First we grab a local copy from the namespace, then call our function. The widget with an initial value for \code{x} is shown in Figure~\ref{fig:gfunction}. %% <>= %% our.t.test <- stats:::t.test.default %% gfunction(our.t.test) %% @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{gfunction} \caption{Illustration of \RFunc{gfunction}} \label{fig:gfunction} \end{figure} \end{document} gWidgets/vignettes/confirmDialog.png0000644000176000001440000002352011406427017017356 0ustar ripleyusersPNG  IHDRvk? pHYs᣻tIME02r IDATxyxTKf&=!-HB" YHK[|]RAQJR+X +P!E^Uv/Lf_DžqLf& <<3g=s.Bٿ|UbûkB"iCWÇ):bI7 \-sugI1c^hjyE` KZ^bRHmm-BH⻈aH0DϯhtC4C !l%ٵuy  *Sfkkn8^KdA0 Ævi b/};6䮻͎V[ZFMiC~-4p˴l&1 {/6[hM{\Ćri bmTjtq޿ # ܽ|6R9~ѥFi@JѳZQ4%/tv8 S51l.;-% B!j`4$]D!^Z li[,tO~O4ڷ[?btkBĨ^H`6FY)KeYZ?۷f[? E1l0j]׻cGٗh Ǖ 3 b%QLTZl㗛[jkkq8]"N#Spټ79NgMY-)124 $sQSL?b6֦]_}ȜL;B$1Vixta2Jv!ϙaÕE#s3SAń[䍱 !Ņmִ,a:5m5RS 8#jO[{ECG0, E:~4&JIb׭6g[s`{!$:^{Mۄ}6L2x$ʧ^B>MzfN16{zt&)mfI Boa_ʰ:J]8.1b)3n2U<{< njם1X{m1qEg+eGIg$ϘZ6OZZZ~4c#s>ظU3dd7ٴZ dY>v]U.w\K8Mۛ4$}`ZugO}ޢ`AIvqQ !DiEE0M&Ɍ'Xݷ&+;/ŚMͽ1#WwtW\n~3 3nEiԎ֖yp,/Dn)%s y#fί_[OSM32"FZlS3QzzZG[szfEtjfXL:vڳcwU Æ.bҰߢd!AQs?X{s?HPTuK7;uĚ{"q]ҳrr#ah^G4:xpVv^qD͎r9!{]J'-*i!IJL(`X6_?)w8qj¢%Ǖ 4\Wu<&#F &f N-&|ȡꢒ |">:|`ے|L]Pĸ&ed*)ǺbMQ,Go::R1UiheiR͐6v 6SL{lKi,+B={UjRwvGJ_0 X^Dgi/vmܼpԤ7XRfQƖNX2S?ߴd?Ǖ:Q$;wtܢΧ'a-m7{xq&5- -mis+ӓT~3oĨHFrahJQkkjz՛q99鯮yd?qI "{O;2( /_?lxwxD ,.vwu]._Y]=A':|>_cSm1 /òze:1fTAvVVy>S[w_M7z6YFjnr=3+'7_o4&zH 0ėa)YWsW՛nU0l w91_Ɨ^7"N&^pٜJx8ju|p8DgOO_KCVn~G{˧  `0V ,ۚC*QٹLU\aÿ]rfgJ"pW5jbyNgW`N\y)-b(iY|FYR[-v; |N7 00dC BHRLf4XzR,.H }n7Ohfq `/bC]ЕaYeVkzϞ=cǎU^ݻ>`FyՎ7nݷv[(..>t7<]=zW_}5}h5 /A.ɲ|Gᅤ~6w,,1k9-ǖgoʷe3sM,NjL_Kk۩gNw-]OaFD0ċ$˒$K}dIF a81(UY 5 ˲4 ð0vb/BHp qb!c8q^$ CU?x! I"$*ސ >Z`(bN >0$HPpW`ȹtdԇ Z(Fz*YI$qx)F$˲,0>97MQz^8Aw0 Z L G.&&""Zɾ~pqQ  aHeYB*Ix>"nȒGͅ4E*"yhJÑp$ O< ngU^cF ./|,˦R&c$x8i$p|%Az5*h`XVDG,cX :m8vw0I%6ʲ,P x#AyVmX!IȲdԨ> xe1SeI#\ 85*Z:OacMt:`2#1w$E "$ " yeIDp့~Qj1 ͩCv .1$˲Ve1;:CHf.*$Q$~Q$lwu4i7,wX^baY>x>4$i0rEI|@%I&UA.JHߪ}!#dY%)8;C'f!#ݞa0j~:#paJX,|[[ё3YpJ%x8"D$%},)mBl8YRHdZzVUT4MG]. ZfQ/;eQ`5D12a!YF,{UDQ>sp8]mGE.;3-;+3lt`i.*Oqt juچ溆涖fɢ֛b5$b8. J$QH$ |q|n!kaYiivŒb24A+E\L8fl6$04>I9V#ˈ^"\-(B$ąP@ UV󰜬 d04VN\`.bưl[[{r|]!DHDۛE2!$bfԚɒbZ- ];3 37CÕ& zCpD2.8! "1($II^glb4Zm_V,WY5bTG j54MttP0(}0DI$IRVFD)*J闕- "cK4Mjq %$I*:40"k]ÔAE1 h" eE)}W hVT1vCDa \р<`DJ{Ku1Jn!.Fؠ!pY\ Dph\p\EpE\p\EpE\pE\p\EpE\p\EpE\pE`A~vh4ar _>rCb[l*|evhƋ." %/?wz\LB! sAG裯(F!¡P1~0&)n:}\q}f{w322222ׯ_ 9mڴ˗_UXS6G&w%ױrܹÇZʦIDAT#G{o~E8w!$Kro7̚5GcQBcTV':'wpTTT<`0q?)S+͛Mfۋ֭[>yԢkׂO_oou({{H?x`YYYoD۷;|ꩧ.\8v\oۈl]͸+rUI.2馛9mڴݻwKF?ZrK/XSS~K.mhh裏v>O>dccڵk_y?E{t;nU1 `'8Q4e22JǾÞ#6l6.l6{<ۣG]`FٴiSKKr8-a؀KfW N\L(bkSxɦ}X}mGn_zP( _z |womQחnp˗^4U{}gQ~Q̸q :~_op3M ͇j&:wwx㍳fھ}{0 ۷o5kɓ{,(̜9sW~[8FsN>G?֭[^/q555>>*,,\b[ly衇Sŋڵ+-ZHIdɒs w9g$Q2$$99qO@/Yn?qp.ZEeee=zSс9q:VkI]dɤIVZh"k6oᆏ?!oTTT5J>3ѱ_\dɓ'v{tʔ)˖-{jjj$I*))y>tDiƬ,9\$=-Mm>ET7o^AzރKYQ%;a1cƌ3fN6l؆ bS?{2k֬䲲k^}α~k:EJ?q24q͈+h+|j;(P*:S. Rǯ?&Y~X逈"?K/;=/ڵE\p\E!e}r-ECcBCeûk?J8yIIENDB`gWidgets/vignettes/testit.R0000644000176000001440000000703411406427017015534 0ustar ripleyusersFROM = "gWidgetsRGtk " buddyList = c("My Friend ","My dog ") Rmail = function(draft = NULL, ...) { ## Define main widgets, store in a list for ease of use widgets = list() widgets$to = gdroplist(c(), editable=TRUE) widgets$from = glabel(FROM, editable=TRUE) widgets$subject = gedit() widgets$text = gtext() ## Handle drafts. Either a list or a filename to source") ## The generic svalue() method makes setting values easy") if(!is.null(draft)) { if(is.character(draft)) { print(draft) sys.source(draft,envir=environment()) print("smudget") print(draft) } if(is.list(draft)) { print("draft is list") sapply(c("to","from","subject","text"), function(i) { cat("assign",i,"value of",draft[[i]],"\n") svalue(widgets[[i]]) <- draft[[i]] }) } } ## Helper functions sendIt = function(...) { tmp = tempfile() cat("To:", svalue(widgets$to),"\n",file = tmp, append=TRUE) cat("From:", svalue(widgets$from),"\n", file=tmp, append=TRUE) cat("Subject:", svalue(widgets$subject),"\n", file=tmp, append=TRUE) cat("Date:", format(Sys.time(),"%d %b %Y %T %Z"),"\n", file=tmp, append=TRUE) cat("X-sender:", "R", file=tmp, append=TRUE) cat("\n\n", file=tmp, append=TRUE) cat(svalue(widgets$text), file=tmp, append=TRUE) cat("\n", file=tmp, append=TRUE) ## Use UNIX sendmail to send message system(paste("sendmail -t <", tmp)) ## Add To: to buddyList if(exists("buddyList")) assign("buddyList", unique(c(buddyList,svalue(widgets$to))), inherits=TRUE) ## Close window, delete file unlink(tmp) dispose(window) } ## Function to save a draft to the file draft.R saveDraft = function(...) { draft = list() sapply(c("to","from","subject","text"), function(i) draft[[i]] <<- svalue(widgets[[i]]) ) dump("draft","draft.R") cat("Draft dumped to draft.R\n") } ## A simple dialog aboutMail = function(...) gmessage("Sends a message") ## Make main window from top down window = gwindow("Compose mail") group = ggroup(horizontal=FALSE, spacing=0, container = window) ## Remove border svalue(group) <- 0 ## Menubar is defined by a list menubarlist = list() menubarlist$File$Save$handler = saveDraft menubarlist$File$Send$handler = sendIt menubarlist$File$Quit$handler = function(...) dispose(window) menubarlist$File$Quit$icon = "quit" menubarlist$Help$About$handler = aboutMail add(group, gmenu(menubarlist)) ## Toolbar is also defined by a list toolbarlist = list() toolbarlist$Send$handler = sendIt toolbarlist$Send$icon = "connect" toolbarlist$Save$handler = saveDraft toolbarlist$Save$icon = "save" add(group, gtoolbar(toolbarlist)) ## Put headers in a glayout() container tbl = glayout(container = group) ## To: field. Looks for buddyList tbl[1,1] = glabel("To:") tbl[1,2] = widgets$to if(exists("buddyList")) widgets$to[] <- buddyList ## From: field. Click to edit value tbl[2,1] = glabel("From:") tbl[2,2] = widgets$from ## Subject: field. Handler updates window title tbl[3,1] = glabel("Subject:") tbl[3,2] = widgets$subject addHandlerKeystroke(widgets$subject, handler = function(h,...) svalue(window) = paste("Compose mail:",svalue(h$obj),collapse="")) ## Layout needs to be finalized visible(tbl) <- TRUE ## Add text box for message, but first some space addSpace(group, 5) add(group, widgets$text, expand=TRUE) ## That's it. } gWidgets/vignettes/gWidgetsImplementatations.ods0000644000176000001440000004272511406427017022005 0ustar ripleyusersPK7l9..mimetypeapplication/vnd.oasis.opendocument.spreadsheetPK7Configurations2/statusbar/PK7'Configurations2/accelerator/current.xmlPKPK7Configurations2/floater/PK7Configurations2/popupmenu/PK7Configurations2/progressbar/PK7Configurations2/menubar/PK7Configurations2/toolbar/PK7Configurations2/images/Bitmaps/PK7 content.xml][s6~_t+|ImIۤMw6S;8( ,;@"AɃ3"s}6Иr`o~;?xoшF2Q&{gRTn&.뷯]r,d8'RF lr>U?.nVfiC{&|:2||+ވ+e7R)~2e\\\ۙ,]QIG}-L/iڜHlN;!)M%̫bXq4QKa?tIlޓx>oe'KǏmmeLfz>?|PF㣣~{.deII%)G+G8f"tJ#cLg _B,pܯ_xiu'(3m&=oA6TpDz12曺v냫6>M|VFJl.&T) *#*XU_AwO{1| .^%xɕJwB|NekJrӨgʙ9}Pf U9;+J锒FrX|UZ&:pesRؗrG//6Q\fOi̫USBTj郗%}ʕ =^H7]D%VN^zSġ/)~P񓓁rP K}qIo\QSR FJU'TkiJHz9UIYٓU`\..'ӥ,ʸ"֓e@D(p{Dz># 0(9i1YeVL G7I+k⪗򏣣Kb:m؝T.r=m--6oKU}xRDo]?V2+R°$FKx޵<a^6 󁷭z;w*׸0hG32C#cg4/<a+T'!)!756&^v__?WtEIRk3A\^s xTieQdwׯjMhbƆCmɺ,2}2ATJR8ǻrXQ@hyFJдWiyY3- F ##YK8HOꝐ Np=W楪DamtI"z>ϫ0KdSbLs̔w꽦'y79UتȬ;{̉R4LƯȘW*Sl;ޥސ;m^%VLu2K6$M{Ld >Y΅uV'4B8!r+] \d ' *m-D\w/,q$Ѩ9cL3-+tյ6(HKA]П4bW=,h\/D= cX[cnk&#Ń⌔Ϋ.TPdv*;!pP+Aа3G)ڒXGJBTlHN73#/Kjv|{Ǹ؞c6 o{qWMColB]՘BB_C#ξj/b-3|}EE֔jy8ڨ>8]ϒ3Ĺ}iU;;>D -Do w-kd[tES#[AFp<ʢԟ#=I?>ݖ6g*q&u< uXdc%QO= 'RR /^m# _o=k( dy@OWn}0{ ƒ\ā,%^x<xܞ@ 'ڡ:jzNoȈӋۯu?VYY= Q׆^o~ qBo~P͂ $SG֗_VkŅGr(q] ۀmhc`~lC/>fg6exB.ppՋc{N,*8CU$K"9GG'\Gӕ'=%R}{Ŋgo3qɋ ' l~EU4š z)c"P!G&Taf5#mɭ6Y"lCdߢHPՓC7#A O:ޤh/ʨc&֧)tÉ|nf|.dsn.4+ ?lNM%%.R9Ydb2Via ,DDyS{}o4lj첑;%d$h\:Yc?T溏`al@J@CWKKQrY:Beg۰Wu-&qϷד &Cw8qybW3p녘9a?҆S^!E"_R-h6&YjOm>jYdDya߷{ N ьȩݺ;XZ Tr4Ȉkf ucJmx#?fJJ} i@-P0G6FXrq&qRs͆X {ɀa10?ƌƛ&kӳE;Wvbno@@P&IB`䮦DA߫?U"mn+H e.R(lvGbp'8s)8ObJ ]{R+DChAOÙP8k|k?>6h?T)UKGw((' ~Q%LVMH tN؏U&iPט{?;aN3˝f(Sy\EmY$_-˔zB+` ` gGP#0X{Oyt7|*g^[T cAxRdIS(&54 O46xOy B=N=rj,z ,)~"pNE`~lkg#Z:8q{X/08tKLLۏX cL]hꛦ.^$k1)p X:]`~ltq= R>HHO mYHCN)jg6H)Y)ݧ~N\ˋ`}VKn~m]nlp\syY od{9(KXS{ pypx}Ud;pv6E\ӆ0}}$숃't#7nw?8a?<d?И |0A0aZaA8Q]NDÈ'EFctLc8 b#Ɲo"L&|-edL2N]v~׵Uk~!!oVjHkN85YO;-N  ԑxf@>L*'>+52ͧoZUIW|( !\|d0nzoIۺR܇oaxD1՗vJ)'oӢ&T` wE}n <'& 㼸F2 \[wGe %8HqBfek{YsQ߃rYV+A$D$*B!w[}@LW"xJ._@VB:Ib rWmq8C\h. ~@rR XT TZ`2HT^vV֍g)/)byraf K7b2gA5Rt 7,q+ڬl[C'{_) , LR+6I% 3k]vrfa[Y|vab`2߹[J3[t>~MYR=IE}65v47̠%@eS,%=~i^AeIk>NqdjsR c95[3]#7wE=(I=X̚a$$H#T)>85M L;P iyYK^#:e3 WBwqK4pЗ!*#(?] (d7*!e{ɬ?R) >W:E2QG]@;Rt,b !)Q9%;ܹvd琽|qW /B $rX8+]]+h-o0GU5"jݐ^.OB"/ }IgnvId D0]QIWIw{QR]/p $<.46дOEڳoVS-w[a^ kIyEu*]&SZjV6גBp:h|byX7 亥x"3SD6>?St+<8cր3Ì&J(XRtWG<0D-oe4oV=ZIyahތ6EhePzx?PK=ߩ)aFPK7meta.xmlA0ګ1 RUUmj+m׊/[cG4i}ND{7F|8u*FW @s#n+~S^r`pFYUh=M=s苅-i夤]ؖТ(^Pg0X) (6Ɣ\ة᭥&vY3/PگK$'ጢeV|).}t l㌭ǴEZ}z8E5;vt4{7H%pA$WaFan͋hy\#Ocy,x{lpҌeٽJ ZnqBw~dI9J5jf)1-Ź֕`}.7,rP=X,`/5+ӏSOzo"-Xz݆36ލ{'y]SfЮB "fmw՟I^{PKQWPK7Thumbnails/thumbnail.pngyu\]. 9%0 a 14 04 4CwH7C)#>}sϰg׺׺uh0}hhhx8zφ /w3]'{isC݊><UPsG 'U"D'~ !PB'_cR y@Uo'p{m87v,f}Xz\GH/.mٿ_J amcf Pᱨc-c޳ޓSbq).6 ]_L)?h7%dHLH؝Y%e2v'vC]5O˞ϯLu71N _?nO ՆcMGp/yyx[^ax&eePéh:Ӑa̾NO#>WW'dH~w^p{ӽ ¸EКGz:_GZ9^jCV)k0kN PH8d4_6 h(t+mj8` {FwjGly ==#3Pa^[VኅZb_=SSSc0wΉ9K4gCD\iI_@|x-gaD'lsUքs5. mН6MNd}<BV*7X(ϘoS8 e~g"6- i[:Q [!*幵[*4 55U٭ }n+ऌ =v ɳ/"E>_ ,#S16.M)1"OQ{WGa.#pgpOQ _;AW;,TW&/ìDl RevΫA]>:XY\ZQ[ e^o:L .f>S)vNGfj%h@+Bjx vR!M,PEړn.;<[)]jLȹ#QW:,y#[-b$M*7*)<14߬| k:h'{233?/ݢ$GtVaVG&~vj8ZiZMFջms\u,7ysEu(R}u(Hw M)Tmttm hx[֬Gf;Oĩӹ_~w;Miz %@@1r@3'otr>Udc_fZ1gJ Ž8z?tH/Xv|y=pIV 1XQFKp_L;;ZQJ[/SoGz)ۃPRW6eR# Vڌ8o064M7aܣqﮘ&35|2Boz*&'')>Dm<;}i1ă۟BOetmX.)!Wo[#a,jk\#W2ub\/ ;Qç e ߺ\":IEhg%ޖ j5$@ODiarZSݽZ)I[4JƆ@)uH2ZZ I+;$B];342WڲPxb+S]k2Cˢ Q3v "쁩[ON;p.CVc¸}baۧ dż{x|7ƿR"lRۉpiTa`tL.ㄤ'%%6G`ffe.r)ǁ JV+4 ރ@u N ٍHG3R#g!SNB%& O'n 6 ܣhM_>Hw y؆ҊXQ,`wmOL6?؄E`ӹkIIBRܫ%/k!ҡ{`b̃ڀkڹ>ߤ']썽i9-EFTї5ok--+\{{]:s 7󾢭X* *ٱj=懘!J YNp΁Oj[[ b)0B Ż6|<+lOug+Щ˘?ZJ>36~8zhqY1tƹD)|oA9 [HI%`- :U^euKX ]wrP"sy,uFI,cvBIPIܣcxQ0y^˒ z W\}lP+< BBԞmb3Q')Kr_\ ,9- ,_:)w9Xb}{kq>ph*?D\wV'c/xb#O3PlMI 3Qvŕ9v~_Jf-xPh F>Mz N9q>o1s5g[W~7o.rȋ 1,Nōێ&WJ@S|N@|jXl\VRPkosJʊBz2u878v&SZ7EH!h'[ވ O@+a= F|$15ON #|E-=tM%-g!) 2bRc..9flrCI>lTr;"a6kBFrY"N9j$F j֑y5&lG ;g!J䞾|F56D.ik!W.k>i#ke,S(Go V^RKոŒS<>mQ:;\$ys[d#4]W׻S2]D@Y?輧gOtH'xՁ Ș#dۡeH m~)᪚tІ;3]ipV9 k#=r7NiooZBtƺv4?l0Kcu`NXtY~I*7CCƬzm WG?/ԋ6\5"ph?I9pҧX6/_.n؇c{{Jrٕs;a NNp(.nj8?8bɛmgElBe˄^"6xMi"@섇Lj#V9MiBM 㹴myhoWP$HiozM'GMQ rqY_A0>3Mh3yUvϫ*أgyT (!ΟB#im˩`|¤~LyLkѱ՞R}LT\;+ !x70nv ЯiN{/Sn% ܸȋt47TBaf8C3Sg7[2,~:g.}(Цn}ω oE75cM=N R9U04>|jlvN}P :]fK1l槰biH;vn|CkQx M>ȵf<3lySy>bp(K#7VkE>'$Llt(?`4ɸ#Z{?vg`ٯ4[FDS W6 s)lkv3].S/WⱯrp>0>Otg>+{#!9ш|{ZT7wttT+,qo:؀BL}O1ݸLZN R`xF̀e)ESơG& ^;1/sGՒNw+w:v~܅Oub-HǓ(f7=fnMW 93>F>CIM}n&A_IwƮI5n]Ņ^^ǒRW L } 9!ǂGo眱Ieu#?*+|ܓhL>ͯNa tUD\Ir`=sM_4DNQ)ܝǙXxâ"^aE/K7s2\g{˛5xd<%0Jhqco!O u{7͈Ejn"wM.@6TFo,}B$@y495@.5ݯߙrTHLnjώ_bKPu+&6"uu)WP&?MuۺrJ5.fuv1sG>vF`N>4TT? lb?2~ 2߰3<%gclMD'j7QD ߊ[͠r,1.o; ·0Ii0CkЪ *(u*lpPok&;Mwk0r`ZiU-ė[낒KK-r KSeפu B,]jkgH݄t;ŵ:4$E5#΂JRRXLq ' !l+e[ّC˜۰.ط7уSf(EVk !P1_U;pڈvGZ^ȹa$/>w^miLt=DY"2=5l=ȳquw09 BG6C+5fWW|as<`߮_ö=G]~c=V=Uxظ\ >w?gw qz.M-$=Ӕ{D9NfCAP˞ʎ0RK;3ύPm8MN<\%+7Ҭ?7G%cDYIozC%5E;W3Hl 2)Ap|qC }QP9W3R#^%** N]] Z2«AMZR){CmJPQ跢( 2ka%U,FLSa諀tCۜmCjY#ZMI~qda3SbNDRRo1Bg>.$ip!ɿGӃd9ȑt@Һyˡ hRR(u9`،blh @rr=!tUԬLa332W1^b|R Qs]2֟ ?Oũ-◃!ՠiEt n]O`6Ru%& 8}!kG"= _ż!!}50y;$NM̞8O}AsS |֭%gQl`SoI85 Wō;D^LPem#!i$t{*^HjPҲ"<~`˗ D[*AjE7σ6z^kX׻:~xԛ~d[߭ T %_N_+íȶ1`\{&iUý-핺0\mfg ii"wuս_Vi1]mU[YQi2*o ~n[sn [M2{FK,{r!cokRf!ǁĘlcߕ2r@NLP~ uX jq""=pKMuu=yr|uȈΥ{>j͹W?)?Ez%MFt]!:2#2!>AMc\?YT yb`yʝ뛣V4"BO[DȐRȻ)o zL =KbDe̡Rbw c!x!|R!|cD*wS)F$B;ߟ Jn&F] Ýr=˩Wo³̿sivE6ٍmHi7 ȜsiǷPKMfBQPK7l9..mimetypePK7TConfigurations2/statusbar/PK7'Configurations2/accelerator/current.xmlPK7Configurations2/floater/PK7Configurations2/popupmenu/PK7QConfigurations2/progressbar/PK7Configurations2/menubar/PK7Configurations2/toolbar/PK7Configurations2/images/Bitmaps/PK7ap?k 4content.xmlPK7=ߩ)aF styles.xmlPK7QW!meta.xmlPK7F!!Thumbnails/thumbnail.pngPK7b" &;settings.xmlPK7MfBQL@META-INF/manifest.xmlPKAgWidgets/vignettes/hello-world.png0000644000176000001440000001311611406427017017031 0ustar ripleyusersPNG  IHDRBO{ pHYs;tIME  e#IDATx{tTս13$;!E D4ĆעBAj %KyKBSkWkzYVoVnʣd<Ϲy%4YYY;g=|f}>լZs;*K}${h#! x=65m"͒mٝEih0H;*K@{zhHv;M&iEacd"xLj}j́8'O|ȱ .WTb&{0/;[~iqYYY<ZK;,D Aol6.-'oYۺ7<*kv\G"?1XoĒPrw^Y>k>\Is2&dHD4u *R̿} Ft)9NFDnlu*Fڷ'S_Ԝi'[<Y9 ô'圮i_ь{G+yD4}e45zԵT`n?: 3o@" ck S#xDUИe0V<9rEJ/.(d0 BTRHApX p벢HDq R@[6[aNo7ؤ<)'3C-ePQJr 0;C&fCB2 #nwwuY#n" SKf)ߵٹ1}`ٯBFE+s::(-=#Y#(d~E@. g,Oy/;ze].7NJT7c[\_wwwH r9r =)iqu绲D`jۖ{YٻrA ?,=N"}أwl~fsEI; c\ Zq1RbՆ>>K-47)U[-N28i4j"!N}it#&N&"e{ ~Ix:c]~:raswa1M6oijuTwuDQ\prg4--PU{]HG~ܬش;;&N:/X#RJ[Y_ĕKntöѦ>CeSF\>?T;05X{̡2!o SNGЂ~ SgI^OD˞}˞/͉lF{GQx"ַH Vi DbV>@"ŋ{׳DTQ' Uks\]sr]lUM^iCڻpV |[u8qBrRNH0~iØ9}&)X/i$h2"Cگ< ZЯaꜝX}%.(^XV,Vˊ>_1z)@4Lg(Q9-5Śk8:bDJ$b}'g_}y^{y< .]CRr~إk 1QQ[\^g%9S{r2Ԗ,^:_f1sx>gSZB|qM)2۷ t HhИO>sYunP g#HfKG(Ծ2zٚzZ֞&~pSB nWC劸8%z|MdTQc0>w(p%t?b2G+$$(䎴46@D{~^DPGDszh"{[+SRW|Oa;쵭ɓHEA&bt377WJuuzk 55gt]n`{/)R)99ծ ,}򉆆][er>Ϭ[ե**~:0ihٲޟM]g'}\ѷ=Xe/_|P "j׮ݻvȬ?vTZa0_zyʔ{[LgK/U k\.wGDEƽwrywu;ւ"RT{%~WUk4RS>>ZmF972III+ЁX "yԯj5R'];^ v nC @5j`_`D?-jDyEf* ej\yP]C#p7jg͚5)))JrܹV5TN^^^VjEvgŋYmmm%0yy)1;vmݺĉ'OP(Wsݺuϟkjjzeee&{*{ѡCf̘OQg͚G)NDUϟΝ};`ho\RW92?἗---~;DSa/ԩSl#G;6of遻koo˓ނ>755n#*gjjjccnhhHMM=r_EEEhݣFO1U[dIyyy}}>{ܹsC3gΊ+t:]ggҥK̙rDTZZZYYYVV̝;wٲe87jSL)))Q*͛9sf[lIMM1bDaaaff͛f0JJJh&ɫZq䜜ѣGO6 :Yx]OD;y?;@0-8;fޜW0Q.O@505CӀAW `(T{ХTP ܸġi  a0uՂp&buu#ryvvvUUUA͕d[n \uQa':::::9zhP,… cbbC0ܹsʕSN5ϯ_d۶mk׮}衇L&̙3׭[WUU嗧8==|NtOx<555钅}ZpaOOO6lxץ+Vou0EQD[00M_Vّŋӧ;G=}4-^P[ZZވwY<vv'ʠI)//a"jnnJ*"-'NII\ ѱcWRR2}}?~RBiڠuhoosa3.NYYYDt%~Op Dz$BGG1m4J/R /T*~ DRPzPCh4Z,/cI򲲲B1yI&)3gΔk ȼy󈨺nK2V W^=z\.WT3f8p@\zuFFqYYY6mȞ={M{ٳǛ!Lն ,5Hn=P0|bu;)jDF5̤j&P @5jTP sp^ @5TP @5j@5TTP @5j@5TTP @5j@5TTP @59n5-h^ @5jTP @5jAY79W0m]5& \IENDB`gWidgets/vignettes/helloWorld.png0000644000176000001440000001007211406427017016712 0ustar ripleyusersPNG  IHDRUlʊ pHYs᣻tIME 8i#IDATx{pTU>;%ᡮ8:# 踏١ZS̔5S[:n[Xly`#H ر'ZŽMO,f}HZ2>639648Iogo}uՕw~=d6ݮ7XoD?FMgb-)Gex3 "N:ÇmVkmu_vdC3v~om.8g2g/BDw!1qtTtURcln}v51OT FHyzM[~ǑAmWWW___2svOs}i'Mu42g#"=_uy SDsDM-1`+Iov@,zIga \s_54 ]]V9ye`Tn.B$rcP4_kKy5کo#;hs>SKD[[ӳ~L Ә=FYSͯi8svW>u?T&M| :I]:~v7)Ƙȳoj_U]#QG x|ș|ڗM|DJ'j#"x}Q*2"Zrs 2i\./3<}~ߧn\q,^3"r4uhʛ*H>}|>U)G G/<\zo]vhE^Rݳ[;.lJW]X_hTڵ[K4?E_t \]^k"W9F-4j$*=f'ʣZj ׬_fH#r,xW^36"X6ݧk(\K= Tqf2Id/ɮ<(wͺ{lm}S3bOzcUzƉ 6{}a9;/>jY8""򺜡>rf{~_\TbSFMʑ: :,pvw0thXWmы.kll,{{# rW<`%tEKX U%=D7 ?DtߊuQ}EgPl MODjx&juDt_UADo9Zf._f._Nf:+{N w6K`snW~HgY;qE{QѸQإo""7n%P֌2{鑹[Mnq+$2}r^S"-aED%yĐZ RI__q6Ʀ>q*f2AKƉawtALDGkK%7іQ90|ꦷ:b16Ǻo^s1-md[9]m^z(:_CX>Itvp_e$b{lMAeEi㭝}Ñ2ޑ\͝ eqbוf"4JDFlɾ|CӚ%ώwk>"jn$x z1^؎KWqzAU Lb&,j˓}Ng!R: T3 | o ~&B_>ҘsCP.9^<>w4˭K  ~oipq7ˍeuyO}6VyU~A. s&Z&r=遼=~O~WlҬ523SS(Α_h5?X]p2 ?,].ެ`vQ9ՙF@ʡ?-[0?Ǥx}c{W0uwKyI^O=hۺOL G104Ub?K:&*sGFƧ#E"؍=ﭲV[r{:1Q-%t!X،Sk,3ޔGwfѪ\p9G<1u3Ƙ( hddGzWI=CDL%}lDIFK }dsV"-D4vkb5ƢŒ!GDjPX:g'49E"8;: v/NJDzMg+]厡S{o':{ϞrdeG;g>.DA6SBwcڜAcl8^N)p^Ή:qYa@_jPX 1bHDYgHD fk>F}9JSs,0ѐ#VV"rr*I}Pț^n^\f|O&lY*8.ld3o鉠5fEɛրLmdK9> r00Sq(|W vV_:@(J 5g9»M3EZ}ijFBL :B@jjjjP37_PyR#9qS%nߓ%'wd-G}@_$XDZK>iY몒+ rwocF-)no"Vp: e2mk* 0:srTAY뮯ʸL<z@֮7^v_:mo-A6KGq#!SKEUM9ّuK$+ɑ]w?>hy)fO1qr<]cZZ⊕8!_͵aTŕ,-ܖas:kHeCCv]&]{ނUӤa/߹wA ~-:T|['Bk*8Nl bI䷴_K=P(MLg9 *9߿|-U$ޅ1*Y3!Tk1EӸSSZ9c|cv@p|a5󞊢nDb<]X zr FE5v8ۼH!xv j 2X^! |?B'e`uJ,)Y=e]?} 9bP^]Б߄Le럜8c׫(,AVdW>>t2BTxfdVp:W5S9JM:z UmsJ) ÑaZl}rmoywy$1-y HiV|&!&6F]\JoI#nC:#"y$.+R40fadӂ=fR2պ乱Bw$Unj %(w5vN$6.c2bDG_K'GKV~vDzRWfMFq(֓4﫩Xl:`Y`JV(Wo[ZX9Z*8_WþTƧ2nCS4oL[g3MzlRd͟1]thP?9O-{( LNMtȢ55?ϓ.:a}){?7I毈o*ίb2'_Ad0߮6 68d"%bfۋϥB}F WArpc45EZO;wd1ВHqU{hZޛp8ϯ}wbMzDrPGrxLN#Vo?%F=8!=lG!m謷uq~T^lfK"Mݏof{,463*>il46˷pFnP:2ꍢ'?2!O?N#r/Y] |\<!fV]jisZ͟iBВu[KJOXYRZk>ù^Zƒ..C//ΛEQ'B.߳KljX,CQG&(pWŞoc\PɑDꔨ &Xv!J~!}udzv;.I\<}Q˸CߋGEfNsݏ:oCkզ6UKiST \f2D yԍҨMѹKhA+ّYփgaB0= P)W,|ꨂ1r>=p(RjqJE<{NIʚ)Mݞ3B>xw*YnwcUݑ: eB6p#n+K4-]Mak~X{lg$j"KOKwYN BGB].7I5̣VdUAny]oƕAuS^ slJ6K!H")._-и}$50' ZĀ;Î +ybOɢ8ŏbAV?؎LLe\?E:ff!n.&=$b߁&&#I Lʚn?󭦪2m伹KO~^ce)bФ+ P 9ٿ"e_|**9i\Xm/GsT;Sh0BMIѲ9pK|?Y3W9VkKTKM=~Ը!B!J"Y,]ij!:v.Kq"J)2ۣ [:22jZ!w9fc>(!08ܦ5oתcFYŸ(s/Fi.+B,HwΧ_(sѡT EXccoj>̟`AR`bsR~Y󕒶ԹUDfhZV"G{FV% jNvd3YNDm-3ٌ= $Y<<ۂXhVe$9Q8]bwL7>V>$YM/-,CFVʝ66L~]B*>L׷@] )dB` #9tcGB'!F9ez^Mт3qZ (E#/#,S $tc0{7w%hGVLwK_GxVFж?ydJͽoG~]JY$52zU6fgCu郾Ά7KS1MƤ+]9ME/\ɘT}޿ [~p|6SxţT'v8> ntH7IdS,JOԬz> *Rq?zDc~l\}^F܆%{vT6OTTzA,yYkym(^O朔~гOzy;)Ϲ^~?hy-V<ے#{9O?Bg.R'yͿ<9=;*A%WZs3}~ù+ӟ=[? q |yR=~tA#??HkY-+ ,S{J dmpMis.ϛGx5&X愇zp\_{eMe.3''IDY^Q2j"h~I^13jo:+O<'RƗ\t;J^zbV/g;sBe,{mO5>5N0IQ1_/I@FGO^\k^z`Dd8lJB %D9S)u|_:۞6?:ݬ 㞆JB2y"oґP)WwjONl?|3oHd/>= PGk<:-A.Γ5(f:_~fLfL' 2X.L]8^nm{n?O?07VɤaΆ֋ƞ6SnØ 4[ jE|y+ !Yl,6뭥GQk>on lH)e55E+Zey&BȢxf1"(./Ĥ Uq̫ko ~"ݭ "L:'Q٭u=}uՈaV3G qbOca3KLd̘1Jrر}ِ%f߾}ӦMٱc KҢHV_mSz V> N7:/\q[nݻwo;wܺu/**BXRR|744?|p(y-[466:uJ(.[m*muÁě0r o]dxt]sYdٳ]O^tiYYiӦ]vƌؼyC{&Ht:Yf^5ؗJ'NHIIqNhii49jZx}(..^p!Ğ0R(bGFy~̙3OXΏMm!J] u{?'^ƣEIENDB`gWidgets/vignettes/notebook.png0000644000176000001440000006515111406427017016427 0ustar ripleyusersPNG  IHDRS @u pHYs᣻tIME.es IDATxw\e'܈Rʼn{+njuUmmo[n@ąDk3~%$>lw]^|](B!v2O} pEh`ёL"SCurcEhOî|!ضP4 ջ8&P좼,cJzcP좼 ;;,$..֊2Z.!-:꼴㘅CEMKVQ5dhM1T'ʝMű'R^sq01EQ꼴uV;ˋl6Ki6|cR( h:=Ņ_㋥|})^NSaQEr(JV8t2Z9tǭS6vq' %fuy9)Hjx~٪ˊ$fx|J1`qxb 9A=QmVTSc (H(.F{1 Pu^ڿ1Z2+;{ۅfblRronŞwȮnfèщvv+2jJhXj^Eǰ:mXU(}Pߝ&MU/Zt٬GZZڋA3)tZxxyQ->+{v1AϬX,q,%漸HBHAR=ō'EҾ18q:(7{{?] t=nJHL߭5]Q^N[085*wibn%EߨxU}i/b)|2q%.T_ޭdiP1p?TB7/OτoҲYʕLÞ+(6Pc7(X ήy:&VB-"\65^سx.2%2E;7AҲٙ9c:7-|d GCHWˎ?TS2n$ ~#犹]Ց+\5[?gK {+q =Hb+_7TH)gs>{(4DpiDX_Y֎FVNOUJ0df~֛W2~U*y̬hi5c6 ?[>UĦHfi,8#bAڡ8R\UUrR8a-oea /FFքؔiF)΄/ٜ粧MJJ@($,Ǵߏzuke8rqs13}۪O|w^mo$WXoI%7X? X'saxֺ]gGli_Wa}*^m'+d^_dimW'6%=MQTQ"Hzdau,m+?2X(i&wDG-b|"5ޠy;=qbE3Fujۡ,.e[t6yϟ2̡XTbՁU"R%g/:C؜8בLt196 )%cAaeEvvVk{9wl;h8We ˑ3WĽ.hcem|+ qNFOnQz'u5|}5),߮ 5k͔5UҘL-w-y7K#8 +BNĘ۩ϣeyYܺ_p*ٶ˶+dTҤ#+x<U\_#wupF!;tiSgKBW~1is!_=fs uf iE[Sb !-[X䥾glE#\! Vor+%6lijeBH_=1m$$fF\&qiwVzgP~0wBtv![虶E8]SST5"l.e"XYr.ҩy\.!~-AAX;X;8% <&wbB!Ό|%#ю`fNyBTMb֖?\}.: q);6ޱyjkˮ6+Ba-&;fQޯă{NIuШi+[_{9}`Ø)<ϭ'z+Kz-uMJMz(oMޕ4[t]X.ܰEW4j.΁"i`{ijPҪw\І~M8V_f mGiok|([i8@,3G$Yuޠvvkۢy3&/_璎e[ϋ s6R2ڐ zk"y7o?ѽUvFb"195,K7򄴡9+[rq9[!g`jZGjSzu-?az"}͕,+=.6Px_^I9|r۶(?keʾ{ujԥQ,O+YZ鉶C49ztn3\dЬsjq~laaHA : _F&Z;Z;|pYNzNIE|BWch!lgڂk(zOF|L^ZuK.:Y&/-1ՓxY^HN(t%r_Fr39<W4XuJ֫c ͨ|J}3/ Rba q}K}iW[BtLyi~z}A//!vL+}Bi }C/H R 0MzLuV=IA[eL 6apu"Hó -Z2E2b|@߈+gr4 EɲhZ5JPp"}\ +4/UyYQh 6q|ilKLEjrz&V=CĢM[W+bsyBPlR*;O Vpllq5PgE<q}=sVCVQgjm=CR!@qELff!|]f9꼴  HW^`im#!ģ߮8|B:Pq)u?Eedd|8 !@}tRYcVM+ 3j/\sٳg 8w*8Uo@u۰U_Qm|}}gϞVX_jqe BCC#""~ŋgfffffN>}ѢE]v6l}͋ZޣG1ɯSS_x2#=xŋj:={vttPX׹/_YfȑOru37o~ɓYC\.>'+Szԩ3fL4k׮xhy8''GOObaa!H7%7111">ERYn1!,&x嚚~5|"7ؑlVBB_ܼ V&4mor)& x_gwyvРA>>>xhsӧŨ˗/amb)iiLfnn.cff8Ǎwض|_VئsϞ%ss"1)#ZHזf?X=n8hyҲeroɓ':f.@occ#51H?Om8ˋ$T}4MP W(2ŲWYJfQ*(ɋP qU,*Ւ }ggg3S<<B86zm+ifT*J%_ZP(DBD"ML|P(l 7m#@7/˕( Rdy{ĉ.9luo+Lni&JeqqXP)ދ΄))~mB. dĤ7>DO[~&Eq\'GٔSNd&r\W8n1Mӄf ~? by,D/77cR,-mN 0"\|[5O.F蝒bު:H !g p/D;.q9\uoWn .}v6;+K$dIZfg禤 |Bih(Ӂ% iCH ! 722-9?3f9վNCfq iĀv1T҄ h EQ|ccӂ|B+,KTx\Ɋ(bYxh[ۀ?~>nI&yy/sxBQ.Ůgl+wGR`LB!V(G^4.,y%M۷jn!C)yyy999<>/\>:nΊ"X(V* BP(U(J D%󨸸GV(1qK_TZ:.+44t ~Wr3$bPhֱ\.gZEJ%3ʍ(Yt~Hܒq̴IHII4MX,q\^XccW^?)oR/4 x\ܹ877;&abK8J]ŻZ4p8//_@4#/fA-o? j::%T$k/q,}SP sx~N"5X811Q/Ru3maE1WJ%O0br܅L7 !$55񸅅2BHqq1wurgx|!_>u|GQzRJy.)Ia% ߐs8۷/^xAwU( A2RmFQQ֮]x<y<iWd Żvtw}s}r{3g31>>Y__7?iiryqP=BH``3ß٬Y3]]]}}}PpfqfôǏ?dȐ]Q 4|>x}yӧO֮][K,qssR(|>_GGGWW7IlW]t8;xb+*z:мѣG `aaaaa1p'Ok;ZSNUƸ{掎f A1w>;w\˟믿1=u~xٳgW\a c??۷o_x]$D"ww/^zի 6mڸq۷opo|++)S\~=88G0Zڻwʕ+Ug:::_~QQz0T2ulbblٲ+VT4ŋ{ejjکSÇ3w1ydd׸'N{ܹO̟?/?|֭[!F TѣGe~LLLLMMurrÍ裏+ߪly@Zنe_GVlݺuݺu饦oٲ_6lwppسgOn߾K!4Mٳ~۽{7sŋZ000P}3wE[U-/Wf:QW⌌ RK<}\nn[~~?0mڴnUUl嫲@h8`;t:th```~~~~~~``СCb3O>}֬YVTT4K177}v4iR]U?.9ZzuXXL&ϿqƄ Tώ5￟>}:s43}7>NG.'$g IDAT$;vO>ݺuS}"|>8OWePM@ۡo߻J$*Ҟ:ujϞ=.wwSRR/_(۴ihѢ9s0U-w͚54Mpw\v bWM}MݻT*thѢA1Ox[nRTccck_Q@ :99M2ݽTP[UU4Oe@m\ti%'0j>5p֭YfRqq\/wtٳ7|3yZzn:;yyyI$zn \~:oh@mMu481@SQ-E@cqޖj8Kw 81cHe$]w+o=q6Ԗ:vVm@q c@ q 8zc@3ZLjlc8600طoT*utt$11yK.7nԺuΝL4X*g̘1cƌKkExxxxxxTj@q c1 А8jMȐH$=e(h0Gm7:33{tV4K.!]:+ K ~ᇪ^Jqr 65PŁ P c1 8@q c1 8@q c1 8@q c1 8@q c@ q 81*T[rѣGl==6mڨ6ٳGܣ~$**GgϞMKKS*O߹s-[T2svv͛܌xݚmɊ+^#ޱo3ʠiZxʕ4ooo6]^H++rg[`AE f>sjd;򵗚Xqk.ckkkR,\Ç8z%ݻw W>c~ȅcǎ-U®]߾};3}ƍݺudTu%^vֿ7ldѣG !evϩC!?!9--duܹ*飚sرUY{%;;[WWW?K.&.N2`0?۷lqLLL|~dddHH'KJ>4M3C ###33S zlէ8*JիK.uwwѩbZnMӪO\?cHvZP %?VF- eq8J4X.vΜ9k;vlVVVmK.g]Zݯ_*~l8V(..J'N,TkKTG#BB-<_%|piQӷl2f̘sԩEՕ\xԨQgϞ}Rξ{Ujvdg޿՛%m߾=//䳥N詨(ֈV=f۷U:$Ɏ9RW^֭[7o\lEm۶e/_͛ y`K˜ZBTZ8w\U>3޼ySX5XJnE7B+mn:Tq 4Mի3נz| 91ݻ*t5C1ˆ#Ə_>8Togg0fggm۶Yti3899ys8SS^zAcו6Vqkٲ%Ţ(!$$ӲeK.kkk?T4vS [bE*9fРAJBȜ9sٖ,_jAT@IDfx<ÇEƪ>x{{#Y %Er\S3m4G.O4Iuϟ8q"wѵkr6Yc_[nU=6b۷iKFGG?Tfƍb:ݫYZ8 @4kcǎ?3oСZzEΝ;KP:uDwjO>i;7Wbou 81c@ q 81c@ q 81c@ q 81 8PCItE&%%d2T @CYYY 5@hh+!##M6ƹwСC/\8]vMOOd߼ys @9rD#q c1 8+=ڹsgLL JcƑ9~={Ϝ9S.,8hPYYY}qqq)))3gDeq phtuu?x<!DWWB}q @nݚcǎ|}rrrP"@ԻOnܸ\.SΞbq P/.\b [[rovQPPBmٲ%>>~ҥжm['''OV8/EEEw޲e S٭h?={\8/G TlC}ɳgP1@Խoڴsrq?~E1@۶m[~2ĉO8Am˙ʑu֐*斜ٳ`u P7n𰳳9rٳgQ:@ԙ{YZ5tK.z83k׮3gE~yyy( ѣGǏ]t~aPF@-[rJDR4h?jcں|,XP_www@q P+2l>>>eVE]tIJJJIIA1q Ps7on۶mmz~lv^_b?~m۶A ~͛rQ}y&J cbyjN:%$$8۷oo(KcٮAAA(,48(NTD~zĉo֬Y]-GoFmc|p=z{. եIW .MP盚VVAԭ[\PdhctJ@mIWWe˖(248>r' 6,''iUC.ʺp¶mΟ?/c诀&Ǔ&M 066pB^^z UǾ WW`JBzܺuw-** {*?v 6t֭G!i1!ݻzJLLtss-^i֭[gee^Bдbhh陓= 8|@@Z+(ť| @f1;|pXm3w}5\]]PvhrqXnFS@E ԻwY3ZP-xӧOx]v CCSc'v%wҥ7*bp% ys7z&O]U-~E5]\\ñ 1Y}9ظWt}BhCSGݻΝ(k8.((v޽6>ƎcBѪU+]]]6jvرƇD8x𠗗W#n34xdEffK]w_~biOh8>z(hyx!!!VVV|yAAB(((x١CBBBpիڵk޼y#nÇ;@ӄ__iӦhB X,@`cc3u'N恦ãqAGG6::9vرg;wLy qӤP(Ο??f̘Fgg{a6DZ)!0ӥR)qtmKKK+++uc -c흐 h&LPM_5bu *ׯ :uj3_i;t:lIǎB@:H$AAA=zH$bX"fԨQsD">nacAvdoochBVp:u @Cr޽{V1_,ch*huzq AƊbsssu01 uVϞ=pryrr2 I ѣzn[׮]q Mݻwǀ8 vک}GM8&4֭EQj:7_HHnX,n޼yLL  A]\]]ܹ=cf ",,E7>BǏ5kfhhq8-ڵkW5vڥ~ Ǡq=w @6 W8&_8$=zԹsgT7771 AkEEEjJ(bн{4bS|q ׳gϛ7obǍw7n^1h\;jw=222??ǠUbbb4<C$9::atYܷok׮a-5bqIwPqܥK_~%##w=k>yo(SW͓ ._|̘13gtwwg4]PPpq4h"BYƍuΝ=wܱcǎ;fee5cƌ?E_OnܸhV*8V?cffq[>`+W xĈ#F(.. =s̺u֯_߯_3g;V m +biPc5 駟ߨhp k׮5kp8OOf͚-X ""c;h۶-zv"}]tiׯ/**֭۶mۺuo999iYdd !C NkRtȐ!'/bcc/^|ҥׯw8ykÇ#:Yȑ# !<cƌf%gݻwPPQqCIII,YfLOOWMΝ;Ϙ1Ȩ*u4ԩnP(۷ŋ===7(q'$Fy1;(rFDZc1߿{}8'OPe'< BS#q\[999|'ܺukM!>>>ءP_q\PP}vB !::}hcǞ?թRv;Ubffx1c`u\/biӾ{TÃ:)S9rSݔiА"##g̘c噙{ZiY ѣGuH$ 8y$,@p@xCא!Ν;gVVsN/!!bjj*CJKKKOO׸t;v(Jnq1;hРsB!nnn2!Xtuu500믿ն~e˖b;wiӆBM*C >~FWH$333SRR̙L izذa2ԡpmVQҤIbbb=z=8PSNNNZ2y<޼ymۆ=8+VX[[s8 OffׯJbܹ(R@WxBBԩ|]iU{xxiq0WZ*%%ETnPqt^%Kv܉j`Z+|󍉉ND58n߾DZU h/2ؽ{ С/aZ/<\p#SUZZZZZZVi IDATԫ1bDjjjHHqX[[_rb5Ȋ۷Bƍ>\&ajkOմFgXs碁8Vk'l޼Y"Z8BCCv_YΝ;o*i+(( XZZ 8ٳ+WĮEk c8jYfoڴ '>!!!Mϛ7jqdee}۷ L3EQ7nܨM޽;!ڵkϜ9?g) ӧO7 rvv644Ǒ8]nذ!668}tBO=m'!_-ԦMzꅽMlӘ1gΜ={H@ub+f@-cP5eʔk׮|gϞ%l޼Y*&23Tj/((GMzzzcƌ9x mũzu^BCVV֕+Wp(Gf͚5k֬+V@WHWW7333??___TFw~ǧn qFqݽ{ɉߔ15w裏pT 8j(DfL5z Ou5۴iS-ZX,VS =jk@kIO>dɒhfJ\\ܺu!gFnݺeL:w@Wh„ 3fxEǎ)-[O(/ w[r<,, q̰tttėL#+ݻ[n:::BK.v@텅nݺi 4::hN]-3f̘15uƍ}*cǎ]dIzz!(C 0ȈHÇ3#Bhժ.mٲرc>/%E4hP] YYYzjzzBHMMpѣ[٣GS:uӧyyyJ2///..ӦMѣGVVF+,, ٳ'JQɓ=: c„ 7nܰL/yK#8^JHHh ;՜'OQ 1!￉s[Y666+Ø1c! 2i\=a< fQ\ȑ#1Bj1mu:::>+!׹ׇN:\\\֯_}.\0n8ԡ"Ǐo,YRu07˔%IPPЁFmkk+X,H$5jԁܹ#H5TAAי./"66+:.vr劓.|R j`_}5 1@o\\\>cF4Z"|||"""Pݻ'O޼y|ou P=QQQӧO?~Q\.wРA@0믿⺏:1bĈsΡc9r䈻?|,ްanܸ|% >Ν;၂XreBTԖBILLJJJjѢP((y*22_T.]t<[#G믿FR w/r9Thiiidd|7o/_:884kɩV5S*,>" xŋ,Xmnn kkkss;w?vګW+W"հWu Zx޼ywiݺ5 q,VG>}48-4|>rQ 1 ql޼޽{ǎ0aM斘 q ۶mgΜD`٣F:uJAp*y4Me1_qQKKKTC7nڵXı&),,LOOdJe MӦM;wn޽qh}zzz&&&O)XcX[[oܸ6m47ݶmL&[jMrGdTC# 6߿fjĉǏGǠJ9s֬Ycggjh~Ž|@ڹs'!d(Fp8cǎ=z(J8nݺ={Z`GAǠ.]:o޼mۢZgϞYYY(4˗߿W_ZgNz!q D&-\pǎ^^^...F)Ǡ1njoo?dBiҥK(4CRRO?eB̚5?@Ǡ⋹sؠg„ nzJ8uw֭ V'NDq NP,Zh͸~w\R A}޽`(k߾ñcP 1uرzK.ݶmn85z'vz,..x"Jp&-22ԩS?F)VZ~Chiz޼y}D"A5;w@ٻw/EQ3gD)ϟkǠ.RSSWZsNE4i/R A-,_|ڴi:uB)_||} .\u '))O?=rwaM] OIX"@)Sa-JeJUw[ю#u>.u-ЀK)+-7o*$A?|͹{דso++B3cƌ:4A.ᇟ|ɨQpuuDLJJ7TZUUU^^^RRR^^&-d4hزeKrr޽{ܹcggbECCJϞ=߿e2ϨQ&N8qDsss4#tm۶<|^F ]vڵrbmmmkk}NSS۷˸ġC1Y9zMmll).+۽!zԨQ}ٕ+Wnݺ4iҤR4 wС%K8;;5; 8pŊƍ?~ܹs18UV]t ,))VVV>>>#BΜ9SPP[lݾ}{HHűJȈӧI>}#""=RzU*w^z6lذ~iرDYRXX̙3鹹UmmmFFƶmܲѿ`bjs]vۣY+ Ç+**$JH$G+W|_MMMNNΪU}]OOϛ7ofdd\t Y ׷kذa 7yt|BȩSfffnnnnnnAAAgΜٺusZ[[KJJJKKݻWZZRG|w} } MKK:ujllɓ'njkkfy⸶Æ o@7?x3 7<<S#=dҥ###&oT;88<}D}t̠NW⬬SN}'NLOO rYXXlݺ>7oޡClfQ׃ !O}zHHȘ1czmB%ɪ*++߿_RRR\\LQTpp/_>x`r_xŋXСo|@#Ǐw aaauuu?/^ HRJ%e2D"Q*|>sppf^XVVC@V(555ϟ?D&&&fff<ĄB:.|!XXX۷ojiip8bkkKlffFwsss |.p8P( 5kH$z#!|>s(B3v[89~]ǩTO~0^MccWZZ绶„ >"(:w\ZZE*feemڴIzK.ݼyvQ SL(j'NP-88yw^___qcc#B ۷o{9s(ׯԩS"""x<Ν;>L?v؀1cPeggC?5eʔիW߽{(TqFkkk@}_ѣ)߿}~\u뜜>rȸ77>HAAA...׮](%88>(Zr ͛wիWO9r$<<|ĈLQ&LߦMF9k֬c2^xqʕ7BCC.]i+Vt钑2?m,$hWS0:a*++vwUO>Uڪ*ToWQ&"_>ydW>d6'JX\WWw=FL3\^__c*++jQ#Ҿ}VTTғN>hjjjjj|ϙ566lBF)//*fWUU=x@"ٙ~'ND"ijjz葧'<}6§OF]v9XǨWVRRԍV]]ieeeZWLVw(8Ѓf1~ 5NN9!&O| Ҍqzz@ /yGGG.+˫-[VYY_?b,--o_n߾fNE&X.:}o."brlrf꯱^ȔbP- _fcftN8)e nz2f.W}sOi4 8qh^FKQiǷHPx{{ƍӟrrr VׯOHH ̜9S{N^)I{ҹBnݗ?˖-ׯ_k566vm}Z[[ !ǎ4i@ PJ*r\6RJ%9(:T*U*3b]\.Mc˗/;88 >\T0ljEq8Dbaa3CVT655q8-:^xR\E]]iV'OԄxb%FPr8:L%X,677gXtҮ6Rϟ1d2SS+W̝;W.r+++zrRhq$I[[S!d2͛5vAR)?$J%hѢu9::N!]Oo2bĈsspvٳg .:t X;vX°Ǣ°( xٲeC)yz<C[O5mk F8~=;v̙3%%%R/"""::u. u}5m4cЄBBB?j:L(sqqIJJjll=o<NNN)_נ(qjj*eGgÞ={rlժUt]R#GT*aе,$hWS0:6 >>>6myfssBx'|BٴixJBQQQIYn&&Օ،;ٳ/ IDAT);v|{|5B RpA EQT ۻwnݮ\./++[jUR*AAA}cȑJR^A4(tk5Vhw}={u?:{Q_Xwz4:K333 !yU #66v"&&&666Fڷov g͚󭬬Z[[,Y"LMM-ZQWWWBȽ{?/\@ٿ?Ç ! j@]K`CC!0KΝ;G Lw(((0## E'&&/-PHdTTTBu\K z}HׯמQ_O?dG_Bȉ'?.\H UOٳgkW;չ;t%x{{3Kf̘A9p% L275w܌ D Guu5!ޞYHq.>feelٲaÆjf[[[SSSVV!䫯(%ɲel 0 ;;[*655}w;v,fܹs缼.\L{.!Ӯv4ֹ;@Azm̒k׮B>}:b333 ѣGlaƍ,?ow333.;d qp:@ WlBH[[DRBl+t<++ׯ+۷GEE 6ёQS7zgbbBI_eR>}ŋO?RRRp'NWWWd2Qȑ~`ggG&L0;;;ӣ㬬Ç>}4_֠Kvۭswhkkl6{ڵ/5Ry3gBm2qlHϧ !F-~V;NNN[l!Bϟ_]]=jԨǏ2qKєJ%!ԴW71+++""Jһw;S{q?mڴlKKKlmm !ӦMcٮ^Z"DGG{{{lC&&&oΝ; !=B :tȑ:uϏ?0K庬Ѕp87nB曨(___.Jsrrb;@O:uΝ;MljjzYX8!D^T'OClu;i1<8x𠩩ի;zB51w׷o_8pz LvڵAB> ] 2ݻu.g„ \.WBu{%xxxOӦM#DGG6}tBܹs-$((㵵 888GF7ı^㸹csX.h<5bB ][1kk[nQ:u㲲2+++FM BYt)#s>k,68~ժP(?1p@;/x<ŽbggW^^KyWùpBbbqvvNJJefE;]K_w} BȊ+ҜLLL\]]-Zt֭O(rG333[[ۨ zFe3:W_ow*008155o:::Ι3...:9bggGwu}INN9!&O|E6lؐxׯOHH ̜9pWJ( 8@q c1 8@q c1 8@q c1 zS]VڰaGc 6$$$tMףA^uY FqNNqb:ㆆ`q c1 )!|.Qkh*gZoIENDB`gWidgets/vignettes/droplist.png0000644000176000001440000001163611406427017016446 0ustar ripleyusersPNG  IHDR~ pHYs᣻tIME; *=IDATxypIe 1 lH4 ,6ٝtٙv&١&3;l $4;%!B(6` >dcc:|ȇCؒi?/x[y* W-`N|xL^ ?|wFX 7_].qgN+\m"jiQoSoKKr:ʉIMz":|]g*U.:$ DtTywWǢTFL"b^cuoYIl3_eXw!wߖm۵/ awMU%أE?Kڋ{ayN\ZoRUhqvwӢp>o/YG}6GU6хz#Adb=DCRJDdMx{ s6vɊjD5N"`k[g(ug1*h0y}͗;ۺfI2c'37,)jtJfӊjey͊p8GDIQT™ረhuqjZ ]Oa>WSU?~S۵Zm _SU"o5Z*tn?_F c_ȷL9#VZT٪ʃ>imK-ihyήa(Ol8%5IDZ&wifwWgw$A0ܑ4y"j5N_4-Iib۬jQۏ}Qc7Rg~_ȈȒY "*w\npi0;[\)Yꬃ.h2\]|]mMԧj^>SA{ӖU#hKNm1fzXYԱPXΔIsB3:{-vWб4fֶ+^ψzAeEg0Ll䥦jxؿ?Lsk[63-{Mh3~RKKҥ9OoU4+OW:]^󦔤E+Nwfھ,'zlV=ݝyQuMMǕq 0׺5 )z3k5OnKT45r󋶖nh53l["< "`2 Np]8ܾ!"Z9&=5&쬌AO4ꈨE(IM3^7h9jZ(uwkmYK&БG+&"=y™bx>8 -]yk (-5exhd;~ȡQ%W,E10,Oh'Gc̢483Ҧ4uݬUgs Vror VV)S; 0/yRN1n݆AXz׺O#NG۰0Y򼮻Y_jΝ7$M>a%s_-yLg!Fh~-P(L!E23'Kf'z|VUc m:"]jyck^;_{Q0{=ug!]o(jy>wٜvwzًھe)?9oQ?0Z(VܺmnݶN NR朡3=cUIȒ|88wgɜnyHUȇn$q74BDq;UUטEQdc__kSC\>`PHqp9EQ&b#/o9ƦfQySĈXKG_"G>YԒ2•#qQG<źßM^V" G.\ji $f%K_fU#I&kF8u)(Z=+(ZcNbF;]qy-3+g2^˗{{_fVN6vzhrV ^nyljepz/iwNd~Vt$M7 ӿ#'f&ffU5>ˡ< fI>V^mkΈs}>31)%5CRHӹ=^U YEIYն1Q&ܾ`mY_"84Z.˗\@ku:5Р~dddllx!of{OmnҜd= Z\Ol{]uّic)K(*ֿU־{^1GGG#+ ݑvwzFFDdYKS3 @D:g͍=ݝYK,VFin؉fW֒exNwl-v/5*9㓜I])29#^$Er$߼gj"Tp Tkyy9d FGWOeU7Hjd%R1Z%,*#&jrjQQw&-Ѯ^`_`FN`|9x RL~gz- 8@p 8@p 8@p 8@p 8@p@p 8@p@p 8@p@p 8@p 8@p 8@p 8@psZu٬ ;p@III\\\nn޽{g^pk8;wܹs6O^>|gٵk}W__SOY,x o/ꫯUWWo۶h4>c8{7n|mZ߾ /҆ z+^y_ױڽ{ /j*NWTT_Q0vURR2d׮]yn ggΜٲe7*bv|…≇ϟQt={<EEE{t|>^QQlǎ8x8-uڵկP(TPP$ʛ7o~ڒ~ӟ]aɧיriiiii)v?&i@p 8@p@p 8@p@p 8@p@p 8@p 8 8@p 8v 8@p@p 8@p|boUy<pp[:$%9 nDĈ'J;&x{_2@IENDB`gWidgets/vignettes/addingToolkit.Rnw0000644000176000001440000003143611651152447017370 0ustar ripleyusers\documentclass[12pt]{article} \newcommand{\VERSION}{0.0-2} %\VignetteIndexEntry{addingToolkit} %\VignettePackage{addingToolkit} \usepackage{times} % for fonts \usepackage[]{geometry} \usepackage{mathptm} % for math fonts type 1 \usepackage{graphicx} % for graphics files %%\usepackage{floatflt} % for ``floating boxes'' %%\usepackage{index} %%\usepackage{relsize} % for relative size fonts \usepackage{amsmath} % for amslatex stuff \usepackage{amsfonts} % for amsfonts \usepackage{url} % for \url, \usepackage{color} %%\usepackage{fancyvrb} %%\usepackage{fancyhdr} %%\usepackage{jvfloatstyle} % redefine float.sty for my style. Hack %% squeeze in stuff %%\floatstyle{jvstyle} %%\restylefloat{table} %%\restylefloat{figure} %%\renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} %% Fill these in % \pagestyle{fancy} % \usepackage{fancyhdr} % \pagestyle{fancy} % \fancyhf{} % \fancyhead[L]{\RCode{gWidgets}} % \fancyhead[C]{} % \fancyhead[R]{\sectionmark} % \fancyfoot[L]{} % \fancyfoot[C]{- page \thepage\/ -} % \fancyfoot[R]{} % \renewcommand{\headrulewidth}{0.1pt} % \renewcommand{\footrulewidth}{0.0pt} %% My abbreviations \newcommand{\RCode}[1]{\texttt{#1}} \newcommand{\RFunc}[1]{\texttt{#1()}} \newcommand{\RPackage}[1]{\textbf{#1}} \newcommand{\RArg}[1]{\texttt{#1=}} \newcommand{\RListel}[1]{\texttt{\$#1}} \newenvironment{RArgs}{\begin{list}{}{}}{\end{list}} \begin{document} \thispagestyle{plain} \title{Adding a toolkit to gWidgets} \author{John Verzani, \url{gWidgetsRGtk@gmail.com}} \maketitle \section*{Abstract:} [\textbf{This package is now out of date. The \RPackage{gWidgetstcltk} package has been written. This is here in case someone wants to port a different toolkit (RwxWidgets say).}] \\ This little vignette illustrates what is required to write a toolkit for the \RPackage{gWidgets} package. Since the \RPackage{gWidgetsRGtk} package is written this sketches out what a toolkit would possibly look like using the \RPackage{tcltk} package. \setcounter{tocdepth}{3} \tableofcontents \section{Basics of gWidgets} The gWidgets implementation is simply a set of functions that dispatch to similarly named functions in a toolkit. That is the \RCode{glabel(...,toolkit=guiToolkit())} function dispatches to the \RCode{.glabel(toolkit, ...)} function in the appropriate toolkit, and the \RCode{svalue(obj,...)} method dispatches to the \RCode{.svalue(obj@widget,obj@toolkit, ...)} function in the appropriate toolkit. In the first case, a constructor, the dispatch is done by the class of the toolkit. For the method, the dispatch is based on both the toolkit and the class of the object, and perhaps other arguments in the signature of the method. The classes for the toolkits \RCode{RGtk2}, \RCode{tcltk}, \RCode{rJava}, and \RCode{SJava} are already defined by gWidgets. These are named \RCode{guiWidgetsToolkit} plus the package name. As such, the basic structure of a gWidgets implementation is to set up some classes, and a set of methods for dispatch.~\footnote{Although it likely wasn't necessary, at the time of first writing a package, the dispatch was to a "dot" file. This caused an extra level to the dispatch, that while unfortunate, does not seem to be worth rewriting to avoid.} \section{An example} This shows some of what is necessary to write an implementation of gWidgets for the \RPackage{tcltk} package. It only assumes as much about \RPackage{tcltk} as was learned by browsing Peter Dalgaard's informative RNews article and a quick glance at the examples provided by James Wettenhall. First we load the package. \begin{Scode} ## load toolkit options("guiToolkit"=NA) library(gWidgets) library(tcltk) \end{Scode} The options setting ensures no toolkit for gWidgets gets loaded. We note the subclass of \RCode{guiWidgetsToolkit}, \RCode{guiWidgetsToolkittcltk} is already defined in \RCode{gWidgets}. Now we make a base class for the tcltk widgets created here. \begin{Scode} ## some classes setClass("gWidgetTcltk") ## A virtual class to hold tcltk object or guiWidget or gWidgetTcltk setClass("guiWidgetORgWidgetTcltkORtcltk") setIs("guiWidget","guiWidgetORgWidgetTcltkORtcltk") setIs("gWidgetTcltk","guiWidgetORgWidgetTcltkORtcltk") \end{Scode} Finally, we promote the \RCode{tkwin} class to an S4 class and add it to our virtual class. This would be done for all possible classes of \RCode{tcltk} objects. \begin{Scode} oldclasses = c("tkwin") for(i in oldclasses) { setOldClass(i) setIs(i,"guiWidgetORgWidgetTcltkORtcltk") } \end{Scode} The \RCode{gWidgetTcltk} class is a virtual class, here are two subclasses. We create slots for the widget and the toolkit here, but perhaps should add others such as an ID slot for storing a unique ID per widget. \begin{Scode} ### Make some base classes setClass("gComponentTcltk", representation( widget="guiWidgetORgWidgetTcltkORtcltk", toolkit="guiWidgetsToolkit" ), contains="gWidgetTcltk", ) setClass("gContainerTcltk", representation( widget="guiWidgetORgWidgetTcltkORtcltk", toolkit="guiWidgetsToolkit" ), contains="gWidgetTcltk", ) \end{Scode} Now we define some necessary functions to implement \RFunc{gwindow} in the toolkit. This involves defining a class, making a constructor (\RFunc{.gwindow}) and defining some methods. \begin{Scode} ## top level window setClass("gWindowTcltk", contains="gContainerTcltk", prototype=prototype(new("gContainerTcltk")) ) \end{Scode} This implementation of the constructor should have a handler for the window destroy event. \begin{Scode} setMethod(".gwindow", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, title="Window", visible=TRUE, handler=NULL, action = NULL, ... ) { win <- tktoplevel() tktitle(win) <- title obj = new("gWindowTcltk", widget=win, toolkit=toolkit) return(obj) }) \end{Scode} The \RFunc{svalue} method for \RFunc{gwindow} objects is used to retrieve and set the title of the window. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ..) { tktitle(obj@widget) }) setMethod(".svalue<-", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, index=NULL,..., value) { ## set the title tktitle(obj@widget) <- value return(obj) }) \end{Scode} The \RFunc{add} method is used to add a widget to a container. This is where we run into problems with \RPackage{tcltk} as the constructors there require a ``parent'' container at the time of construction. As such, we don't have both a container (\RCode{obj} below) and widget (\RCode{value}) needed when we add, rather we only specify how things are packed in. \begin{Scode} setMethod(".add", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk", value="guiWidget"), function(obj, toolkit, value, ...) { ## how to add? tkpack(value@widget@widget) }) \end{Scode} [To avoid this, the \RPackage{gWidgetstcltk} package requires a container be specified when a widget is constructed. This container stores the top-level container so that a \RPackage{tcltk} widget can be constructed. The \RCode{add} method is then rarely used publicly, but is useful when writing the constructor. It's arguments for placement of the widget are specified during the construction of the widget.] The \RCode{dispose} method closes the window \begin{Scode} setMethod(".dispose", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, ...) { tkdestroy(obj@widget) }) \end{Scode} Below we implement the basics of \RFunc{glabel}. No attempt is made to add a click handler to this or editing or markup. For now, just setting of text in a label. First a class \begin{Scode} ########### ## label class setClass("gLabelTcltk", contains="gComponentTcltk", prototype=prototype(new("gComponentTcltk")) ) \end{Scode} Next the constructor \begin{Scode} ## constructor setMethod(".glabel", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, text= "", markup = FALSE, editable = FALSE, handler = NULL, action = NULL, container = NULL, ... ) { ## if container is non null, we can evaluate expression if(is.null(container)) { cat("Can't have an NULL container with tcltk") } ## find tk container if(is(container,"guiWidget")) container=container@widget if(is(container,"gContainerTcltk")) container=container@widget label = tklabel(container, text=text) obj = new("gLabelTcltk",widget=label, toolkit=toolkit) ## pack into container tkpack(label) ## add callback ## no callbacks for labels return(obj) }) \end{Scode} The \RFunc{svalue} method returns the label text, it requires a little tcltk voodoo. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gLabelTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ..) { as.character(tkcget(obj@widget,"-text")) }) ## svalue<- setReplaceMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gLabelTcltk"), function(obj, toolkit, index=NULL, ..., value) { ## set the text tkconfigure(obj@widget, text=value) return(obj) }) \end{Scode} For the \RFunc{gbutton} implementation we show how to add a handler in addition to implementing the \RFunc{svalue<-} method. \begin{Scode} ### button class setClass("gButtonTcltk", contains="gComponentTcltk", prototype=prototype(new("gComponentTcltk")) ) \end{Scode} As for the constructor we have: \begin{Scode} setMethod(".gbutton", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, text="", border=TRUE, handler=NULL, action=NULL, container=NULL,... ) { if(!is.null(container)) { topwin = container@widget@widget } else { topwin = gwindow(toolkit=toolkit)@widget } button = tkbutton(topwin, text=text) obj = new("gButtonTcltk",widget=button, toolkit=toolkit) tkpack(obj@widget) if(!is.null(handler)) .addhandlerclicked(obj, toolkit, handler=handler) return(obj) }) \end{Scode} In dealing with the handler, we used the private method defined below, rather than \RFunc{addHandlerClicked} as that method is for objects of class \RCode{guiWidget}, and not \RCode{gWidgetTcltk}. This awkwardness can be avoided by defining a method \RCode{addHandlerClicked} for objects of class \RCode{gWidgetTcltk} within the toolkit.~\footnote{This is a result of the way dispatch was designed. The toolkit information is stored in a slot separate from the widget provided by the toolkit in the gWidget object. Dispatch occurs on both the object and the toolkit. The method with these signatures is the ``dot'' one implemented in the toolkit package.} For instance, \begin{Scode} setMethod("addHandlerClicked",signature(obj="gWidgetTcltk"), function(obj, handler=NULL, action=NULL, ...) { .addhandlerclicked(obj, obj@toolkit,handler, action, ...) }) \end{Scode} (The internal function, \RCode{.addhandlerclicked}, uses lower case letters for now.) The handler could be written as follows \begin{Scode} setMethod(".addhandlerclicked", signature(toolkit="guiWidgetsToolkittcltk",obj="gWidgettcltk"), function(obj, toolkit, handler, action=NULL, ...) { tkbind(getWidget(obj),, function(...) { h = list(ref=obj, obj=obj, action=action) handler(h,...) }) }) \end{Scode} Again, \RFunc{svalue} should retrieve the text and \RFunc{svalue<-} should set the text. Again, a little tcltk voodoo is used. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gButtonTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ...) { val = paste(as.character(tkcget(obj@widget,"-text"))) return(val) }) setReplaceMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gButtonTcltk"), function(obj, toolkit, index=NULL, ..., value) { tkconfigure(obj@widget, text=value) return(obj) }) \end{Scode} \begin{figure}[htbp] \centering \includegraphics[width=.4\textwidth]{helloWorld} \caption{Hello world, how are you?} \label{fig:hello-world} \end{figure} Well, that will let us make the following simple dialog (Figure~\ref{fig:hello-world}). \begin{Scode} guitoolkit = new("guiWidgetsToolkittcltk") win = gwindow("Hello world", toolkit=guitoolkit) label=glabel("Hello world, how are you?", container=win, toolkit=guitoolkit) button=gbutton("Close", handler=function(h,...) dispose(win), container=win, toolkit=guitoolkit) \end{Scode} \end{document} gWidgets/vignettes/button.png0000644000176000001440000001230111406427017016107 0ustar ripleyusersPNG  IHDR~ pHYs᣻tIME8:^z`IDATx{tSU'IrWi>A`x(q]`Eq5uךYu׌:5 ]#2ع̽ҋ"A-GZZRnҴ3G6)C9|>)CDD-䝃yD vK222)6QRr!-s 6!n+gymMRgt#pAt:O%&&Jf#"0ӂ 0 $%DͦS9 #ܔ!b&)gႷ9~(#2h+/>Uhi|wITaiFל*\vbx}tŽ ʙעEY WkJ$fMo R3䤋'{{F)?w#IMMnEY좬"F(+>+%~z٪:m[M;1yYSBt8t8Uj7ԫZAZSͤc\&K&f2~+iJ](>afΜYdTb՚u rx=rPbPi!pc^|zֽml S9#Jiqxh=>j1Ig,z=/5Dtg˗. 3I%eW, Z":{qZtCl4~d4ڝc&߭U34| g9FYOUW:qѾqv+m<ϛXRLL]"Β3$[W^hkxM#@$iZwdL~c.%$rE "1"α@,Ȉ#2/;-*"VEIr:"R8hTn L("sa^Ӓ:]]ך-Aj9AecFU0pmΏOd(c~GN$ɦ>QqA68ڼ5K/߮R<ρbIqzFΏ֬jjV|0LqgaK5{z:Kt8:h.VɨTku qovujVM==q2Rnظ(+ʌI-M-M#"9N{OUaHR$Ɛ;|Q2̌8,dLF)Zé//Gx2^W[_$#",6^%fdT_cMHo$ܤp!JJ1{ =ϲ6 P)7=ԛy/"ڽnCo敞/'+w 2久n|2{򳧎z}~F1e7BVaŤm cA7&%^oԲ ]Rr(ڡZS%CJ?|`eK'ǜ{/_ Qfmp+uu3g>u~uo+ǎu]lZ}l9V0+5&-MiӉ#n؟0(ƪnپv/rednڲ]RqnEƹhm$"V7pZ&V1 qD4=%5DTQQ󂳫R].^&W bួufKyUEXÛ7&#nohLHKN&l52*%5g>8 ͜trQ|\l[UѻNiTDTe1ϏcL+dِn2aa,nV/tw nV%ˎ}n#Vx:VQVSQin ;)ɉ}0竬%OOIqwY̲竲`12H{z:NKDW**cre7H9-?W37+w^V_B\l$ ]].:)InwQ}>_mmy^a\9?/`[w#{v7v{1Ҿ?K8sCQ,YVqӢ/Yuj5˲_\[KSeEy&)gzZ,:#oW酢ٛ`UM[wQɹ7|ow*jx kX=sEL $9ڛNe~Ţә.6gwɲtq(FD% #DzGK[kn "!L ƴëο\'qQVrkb&=~ E`"ꑃ㩪IM2={!bcY-l(KJp31jZ?8WskGqJej\wk]|||WWW5ie h[#a6[U4mK[bfjAuz͆_t`gf&E%%{=%>>3T K*RS-~?.'FE% 0RNYKJ4Z( 4vM? N7-"Y9Y9xFv*C6b ε6+jfO 6W /gMolku)3­9eO]UZ[EBRJ`Oo{N(̖=bV˅Y"g:KDZN<#&.rDV}^\[]Ҕ\iʤMY*0ߩx &Qjjjn/DQ"iNO_-݄13nn nsAo/->8p'P DED3"2ODҘLd0P5s:#0Y#` @8 p@8@8 p@8p @8p @8 p@8 p@8p p@8p @8 p@8 p@8 p9dYuS.^9C =ztѢEr^^^vvby׃y饗6l0tvg͚vJ-ZTTT4v,ߗ.]:m44W8p +++*//q#T ?~lٲh4X"h~_ܷo_fffii֭[u:#<2ի{n@D8xmۈn0pΝ/rff&˲9s}b1Muh~ /++Wh4{}BE޽^3gZݹs端:Zll̙3ݻw׮]{uŊ 0p׮]gaO3 M!7n8$ҥK/_* ,:\`K\zÇ> 衇O8AD}ʕ+4lC:>nwc׬Ysq۽gϞG޶mr.\8RE .rjj_|1tXPP0k֬5cccg̘gϞpʕeee{>%8 w7n>z:Sc=6Ty_~yٲe z'bbb~ [?gy"$tD~~  /syޛ{{Ahz~? 042=ll&N0=|+ yVMrbdj;N^LA+uEM=@WH56ETU%C6QSIqq1 q(}t`0p YqqP ڎdA3kv~n$v֫utt('Lr FPx rq`vmڎ/`<=X+W+^ꋕ55{S`䜦N@{jk k$:Icڊ0<ێ\y&D4тf~+=eҟHMRQƏuyeqq\kk̿()BZߕTΚTOI$r/.{SM0PUp#@!ՈJX\cSoR" A t::eުr>HVWVRR訬}ZOTQ^q`,^KȅOKIYU!x8 rr 7nc rrrpnavDaI7f>/混wEJms>]X[]0#KVwtt;y$a89.TcOp$q1LΝ4- qGD8`aƛ(*- L #*O7b|IQ"Ayy!" YSUEyL2EGU "+޾xJWJ7&Ru)? Ф|^KS}K)YU[D BVUb <.(0644 vQBmqKיqBN~HMNod#KVqDރKVJ\7 mǞD8LU~@^AAh N0t4U5kie[w,yJ$dtA,aIf' O}_T_I_]S{/tW~yjzmݻs wvv-Z0fnf񴌋SPDwȗ_ 0ܘn&/&)5h>r3M7335cڻw$741`g[L'ߺ}D&+)+c0}muA54 XvKp{Lo~^NlU%ϊml c[ێB5)*px<tw >M5eA8])RH~3c翿44>0&ff$M4v|>ȱSF&fc)RAYzjƢIPF%K Id99+7܌><5I<ujlF<}@tu߾zoҦLP07#()6*ԢqcҲrcC3#o45(E/X$SpY8pJ #q)5KZm Xnϊ* p=[mG>*)3nn|ZYu_jL5#T%A :8k4׉P'if΢kVrXƦ41t- O $թBPDː]GCTS]U_W+XV^>n=GDQQkLOrrDGAj]E_M|:O=}C ^WUUUTC(*"MMmB9! 9TNIh;Ӡ$yswu۔h>A s9AW i54px<U q/> pA֩ N)!XlkKskK2QUAД2[:O~Q'q@"8Mv:1Wo* jʝ<*?|EG^G!HGd9.\*̉'eK(ʪtm19>JJTd]8@g90hTLZ$@‹.|uN>r/><S D뤙TXWI[^NaE/˘YrX<K)@$Nʷor <*s^iqZa4]ye't(S';  n$U(:zDU8+{ 6xSTȑ4:ӵDZXHwf/y6vKW/]A~EaUtvDW]}a ʺ-  NpQB]Me"Ĥj tL5DOs ikkSP;+*._b˖,Z0o*߼蕿TWSYh~ՔjY4I۶%^NAQQQMְ0MyVlľ|cʹKp,VN@_ Hg]]Mz Wp |LUMX+@PWN]=c. NJYs|nìgEVw;֖=a:o@ {ϒkvK )uE9Lv'@ח<54 5F:::+ S075 ro̫U&z!_|.,&"BPV)(|~ftOw~3XC}6?u5X`g3v횕= FS9\t̻r6C1RV^t$[ sjF &IaFRm3 Hm4+A-m#q7\9JRmk;Tm[U2SN?XՄIM/LLLʸud5JD7ciT3Sn؄a0qqyKsU_OY`J 1 :zM7RӧO15;&5773֙xov_UueeO-iƦF**D~gguuMb,DFwhkPkj&^flJ#'ە'ihAZZZH6ѵutvgk?־a&'`$--mqrUԚ58E---mmmOpxQIIEMNv|WWȹ RmG̐MR䯻::-<WSS{7+;UXUEmI'~$S ehQmgzZ⢦>h`lfdbGUPRxyqL12):Xyy8^RRbf֯1ъ f(mG044q8Vcc}gg'^AAM]CMD ԓYC,P($:ISEE`(!? ʵIh;0p8ƿj{ ƏW[wmG Gk;ZI-r'ڎ@mG0ܑH[~>سgOmm-Dh۶mv}YcRR:[WW7:wYttYQ{ `K_,Н 8 7:{F^Y%COO/%%E@Wd@jz@۱{^=o߾ضmԩS8 {/h` "@۱ /NKǨ4 %(eem۶ohM8QTTchh`0.\梗gYΟ??m4}}}MMMBO8aooOPlmmϝ;'@d (ӧEguss144\bEUUѱ.]:cƌ.jؽ{wiiiuuX=?ӑ#Gˣw%Y]!sÇ9rdhw޲M6D"׋%͚5KEE۟L`0BCCݻft)noo Zn}Gv6mZbk׮ݳgOvv6svvF x@ 1 6s\}}`OOOapĉxCDDġC_~á)ǏwvvVPPkkkWє7o -Zo߾n3ЗH&+++Ӷh::]YYI&Wb``~[?~RPP~+?ftZMM A ieeg}Fd2D200{,:2dc۱cDŽ zV^˫Wʾh,+`zLSVVNLL|emmmEEEgg'xR^4000 LJ@ h4[</""=փ`~;;;VVVoߞ6m;wƎ; [yynj 8HݽŲt,U\/DS۳֭[7 [8v؈DǿRT:rڸ\nTTNRWaÆ'O.\qƵkX͛7ϟ?@رcٖ;w?8Ui,w޹s>>R^3"DGЕ?uTG>xF{:::^|#LYx1\b#[fMff&Nj߷o&P(3g{\}YXX(((3~+viӦQ(G$t⺭(i۶mC =zh"]]]<ORd٫ϟ?߸q%@ cƌٰaCIIR$-N!0m߾=((H1::Çeeehk׮]v-00BWWLtQQUUU)o޼裏?~oַk׮ N/7n(c򈈈7nH`.]EEEEEE'O={6lfY,5bٰ+>t:;;[8QSS3k,(*22211,44{t:00P44ŋD/RRRɯ^N,X@ ЈJIIj &__R8FWt!!!,d솆6d2Y,VHH{ 'm#1:4˗ 6mBK=zN>?)FOJJBsssy<^nn] %a9vTTT-Zf?~mG/K.66׳fBϞ=+e?z3)qCTQ1<,dϞ=---k֬9yݸ?~AXg}ەbӭӧ۶mھ}{o0ڳ3LRHJJCSƎ{=}}}Iu|rĉ݆F7/_=jcc#:ׯMMM_~ NiihDЁ^ss~ H))))/hx{mڵ f|:::hںR,hwV(f޼ykiiYXX(e5rrr6Lު@p8z%%%ƍtEYY9??m}!۽{7- 3>׋#HNNR 99`m岳UTTrѮ pOYY911˗p>==]j*Bq㆙଀cڼys[Ճ`_Uttejjz9%%n#sD/!`hEt sEDDa%8w}wĉǏo޼碹ᴵpۢY}$0aBnnnbzaaafffpVŪXZZ.Z… YYYbelll;6g*b555'Mr>,ڵk~~~cǎ%X,V]]}ҤIwͥReXϟ>}:LbڮeDP?exUUՙ3gw{VW~~i4"F[~}^^go7 AIN{{{?^졎Fwww:5x+W[o߾bŊ7nOJmٲѣǏ  C'GEE<|0((諯qq۷o߱cǞ={Ə󳲲"##seddtm\;6""biiiPիXy}G}絝?3!]]PP:^VL^7 # T*NGEEqܶ6.EөT]I4qDUV3&88qÆ zzz~~~AAAﲅ nܸqڵ,kͲnnn|󍩩޽{z+,,, @SSǎζ466޹sذҥKEEE~>"^A'O޾}RKKkʔ)+WDX۱eX^9@{;99uU?Q^9}yG{ >p G0 VƦ?m>h/ eUDG#0H ;D? #@tKb$tZҋ`>>ptDDȒ ڣ/) qQ ;F^w_ONRƏ~wںHaW3vuW^۷RNN4--m7oބ`Fdzg>}TYYYbڵ#`/;ŕU L)***uuui4_|$zzzg_tiUUZĉ ܹs.ի666gΜq|||  ƅ ЅbD#<:8pb͞=oyXwww{{:xΝ;KKK=zdnn>gΜЯ$??Bl޼-O?9r<**j߾}.][PJJnZVVv̙^rEMXt3 \nDDDBBBF$*22ݽK0£G}(//3fx{{WTT -Zo>sqggg _My~<~k={¸q㢢;Y6l֬Y***x<ɓJ믧O G*4k֬Yf!g RYYRQQ73VSSCB4 ɓE=z$Lwؑnݺ`Yj^`AzzzsssSSSZZX+V  GxӧOoٲ׊W^l0رc&F> 6s\}}`OOOnnn|MNNNggƍeyڵ{phTjjjjj5kᣐ}^"%嚚 sw}^zʪUVZue\\\zd2L з%%v<.]II `244҂333"+vrrrf͚ue 05556-0;wnFzDG6bY,͆] `FG>bL&nhh`L&b_( gϞ,\ٳgpl r9?JT*ߟpp^]]`08`GGG$ŲDb\\\jj*J:t+ @UUUUUbyyy:tQzzEHAAAg>}`0 ӧO!AAA}X狦̟?ƍpxvfΜ3o޼v!`GǴ4O~~~nOd2Ҥ@d2F[dIVV^\\saֺuÇ=z4>>> E{{{RR'|"?x?`$GGABCCT*Nrmmm\.7**NSP)ݻd_˅Yd29!!!55ND)0CMffewzzz&&&Nb;wܓ'OUVVjiiM2ȑ#>}%h8#AD aMϯYII QٹXUCBBM0֭[3g΄xxĮf:::$hf27o|PTTtĉ8#v(CSSS55ns=<vtt8q!'D%K$0HёfX,kkkmmmkkkfaWA?Ց'77w=4iRff.799J;ܕ+W:u N60Hё燄X,&fl6dX!!!|>_ʼyyy$kg|}} .\3sP^^^mϝ;dIp`Dp.pT*R冇Kwڵd29))kVuu'p8ӳF\0ݻwOCQ@ x.9B[ZZ? M/Yp8A,H$M4i…^b%q!///*--=ts7qb)455`G}FE*++.r)2 ,>_z.fΜ)G8>>v,+te˖8k,߭`0/^(_ k;"JRtzTTmkkrQQQt:J8&^#>LNHHHMMt:=99911)= Y;v{ӧ?󛛛KJJ~7CCûwȫړ'OhĉWUQVV8qbjj*/ڎ`ؽ{Ν;ɓaaa{Lr)>EJʢh111}CS||< qqqh F4iR||?j*,,,vvv?s:wΝ^5cƌ9s!+: 9;; (WQQ #s}vccuhmmڇ%:::G}$6= H^^^t#!WV ˪Bƍkhh(--C :O8ٳg\nkk@ hkk+++;{!p'`hkjjyYǕ+WfΜ۹0 ɼ~:5 ;y= {{.]mGGGuChaaч'OiӦ>@ <>ĵkv۷O:駟999`bbuԩ;wÎ pYACCCׇ^tU<<#fX,k@.UUUUUU6;a07oޔ|[[[QWW@t aXL&f744l&bBBBrfh4mmmgg稨(w={`…b٤ӧO%GC7o޴/1h {!<?$$b1L6fL& fLHHXt)B8q? Vٳg .{Iz.`Тȸ(G&ȂFp.pT*R冇K3gNFFƫWΝ;w;v՞ p8OOϚYrftm>_pdA#IMM#bYD"1...55UR}…zzz摑gϞEs:b:$K.`>>ݶx<^DDÇex#Ɍ=N`ij~^9::v'222RPP(**aqEG:}y:}||tz.^xÆ X,رchuNjddxbA322d#m>`t6uԌ @T~qRT:rڸ\nTTNRf۳g>gd29!!!55ND\ 5441==2cA,w޹sw#ɓSL̄ :dXQQ1pttmii :dpF pDQ] ??4 =i$ PҞ舎42 ;wիMC^EǑ}/^ zwFhCCUV\vQ^^̙3GCt`s̙3gNGGGjjj\\ܟzy)**^eee)))K, [o޼ADWWw4lzG5k酇;99}NNN򋽽 `/1KĉEbb+(|1<?<)))--m>}卞M<A<jժ3gbXnnno߾t+ f=1;;[ ԷIII贯餣>30aªU,Y)؈|;/rl,BQUU-..677CQbZWW7j5ςwWu ã&} L$;::޻wvÇt(#7E$}߾}bKv$''nTm}NNz>^㏽l;qjhh@vjmmm߿B س?xŊ6m=8L577 @dƳgCtG͚5+00000P4ի666gΜAI$M/0I"bccttt WXQUUc=0`Ž;7o(-3:E{͙3g۶mk׮MOIIY~֭[Μ9s+Ww.--|{-++QQQA۠KMMmٲe} hmmFۆ­Gлhb>2~8 ۷o߱cGVVVkk+ǻuւ P@;wL2en>R} %>>ǧ~ӦM|MNNNggƍPۀۍp!:NuQƍC8 :L8{ikk/X@[n`cc'DG0 XhiivttDDAAA6?@TSSS^^CN|d곪{`0Ywܸqwyws\. ޝBc,Qd+-]"DB+iW)Qn*7)]RiAH[т6-q~|c& x3>3y9(wGp8pT.#!X,**65xqBDEE!!g}||޿߳gOWWWL+n޼9vXġs, ɵYjVXѡCΝ;۷W^BfΜD;=w۷olvjjŋ'MD8B+::G@vloߞ3o<099S7:@ӦMqĉ"Bׯ_oEvDvDvՈc- m۶v 3fFa89d"ȎȎO. \RMMd63:JJJ!***t3g.\fBc:? d6 WWףG6Nt钕nݺх&L8p9szv6ƍ֭C((/_Z@Zj~*jROxyfٳg/_ʳgϤwPPڵkP ;BD]vmΝq3f ٳ"??#G]Mdd jgϞ!Ȏ-ڏOԅ/^hΝN4PS7nhҞ+/;?qফȑرU.߿Q r}ZMM-::ߟw9nYǎ޾}fo 㓖VZZJ:::BΜ9\xqʔ)C틛: fC###߄zQBBӧGBbccE:t}%6߿BȻwb ?ݝВoδӏ;NC ?~,**ڷo_VYE׸?zf?zhʕ^^^iiiTTԂ EFFFׯNJJ;w.ݻ%%%EEEnݢnBQrBȶmBj°ׯ_7~+++,--EEE{aaaZYYϟ:u*P--wkȎXpܹs]\\gNNNݻ͛7nH* 77w***K,͟?WCCwޑǎ]N;|B=FW)7|p{{sΥUUUeddDDD̜9shdG!'&&֣G\4h6Yf͚5;%%E]][SS+B?IAAZz6mqͽUNcw5g hsHKKsR&=֭[mhhb?~ᑘ~z! (^2dBNjj*u~w9gϞ-[l̙p#5N1RW6S#""!gϞ9sSu@Ξ=;uTL6.Avcƌҥ]]]P4|BҥKGfddPpm\999~պtϟ?u-,,fG\4hdA~QQQGsU=ijjD;UTTNIIn&%%}47odffWC]U}Gh>LMԮ];II~mo=RzXZZeeeq8̰0w.ӧO[XX?]RRPDH UT+111))޾ pOqq1ͦoSN!?d2{  /////O 111ԩTPP8q"ud;z)S455DDD444͏=/++#W;wN__]vÇv߿aU>ɡG~~9d_|Wt ii&h%%%{͛'OL9q℥n666ZO8X(%}͛:vW[.22&22Qj)?t~wJHHP3f:tȑ#eeemll~i,98 ;<_z;vJvuܹ&&&W\233C\aaݻ}555^:zݛ &$$ 4FVk6ieHSSS[jժUBBB\yyy~jFc||<;99!)**j׮CkHNP4~xzZg֬Y{1`>+**:u&%z©G !ĉPG߳8j Ͷ B?ȸy&N!طo߰alllv{'O1bOWj s0ֳܥ Aݼ\@!~2C9s&>>j,޴\\\V\yqkٳg˖-ũGdG"[Qp8޽tMOO[nuܙϗ}􉉉=zt]ܺuGƍCnJKK>}zhh(5#./^fZg۶mVmзo_wDvˤIvQlN_gϞa~QUU-**;B-?P)//6mڌ3귅{n߾9իեȎ|-Z$++S-XYYrڵKAAAFvOtEVV ϟ?_p!$ѣ޾}{ 6Ћ233ۏ7.555++ŋ|xZZ455V\\\IIi۶m=%((h,s111TΝ;mۦbԴ{.9ΡC{AjbWN0 aum.uUׯ &ȰX,===\&=x`B(Zuuϟ?#Ȏ|599ytvŋTTT*'={6l0zϟ'ܺuKQQqԩTr^n<6UT {fΜ9FFF+V8~xvv6ŶiΝJJJF>bpٱvݻw߱cGdd$]߮]K.>777''zL1eʔԸܹs}*IM7o|i55hCC_zBK驥D{VחS$$$>}1667>>~̘1Կ"55޽{ܻwouu͛7oܸ /]tΜ9K,^:eg9::JJJҦ<==]\\:uT{$x/ޕ0@EEݝ{jhh;22رc -}F(Z(MMB\Ӻ1,lgn ** O.]4fyoCx≈{[n-7otppHIIر#>,-[Xpcbbhll,<~xdddXXuV'%$;g4GaF[!Cܿ_+ }}s禤lڴIMM~!h\;vTSSՙ-555E4Z:ݻw [ǍB]w;;L777;j_|9s B 6Jx&Çɓ':t‚.9rݻwGթS3fUiL5:tIQQٳgBR*{{{WWWHи|1#pyꕝݩSTTTVА޽{Z/ ή  >}4a„;v9hMFqaɻw<==Tmׯ_Cvo߾Ι3|ZQFݾ}[jtҙ3gՋj!!!_agq8Z(77d„ k֬A;>iii}`5?C~}||\]]1WpӧObccӗ|af 6lӐAQYYY ׯcǎ566޺u+266l6lذzjz2gޜ!AAAh;!;~mnnn$O<966m+VXfMY[=<<?~k.]]]BHJJڵk|1իy[|ɴiӸ IHHŋU8zʟb0w600F Eq߾}...۷o߾}xܹs5/.....n``,؉hsAjl }ǻw ^^^V%h>aɎӦM.6mڍ7Z?77믿H\\Z_ADDDBB fddf͚ZLǎuuuumNjjj\\{޽x躰dnjjTu1o>>K.#[n...CXcqqwTqqq+ļx{tn+V211155]l(==}[nG4++sUTT4~_~}5>[ի\Sc\X3_VZk׮l]n]aa?}ӧׯnذ ˗ǯ^z̙Fѽ{k׮5~\]]۷o_o Ev|w˗/555>b}߃G5009zhhh(f[YYM6?E={6?HݻLQQή! Vŋ111hAgGccjO'8s挱q+/Z*wC۴f))-[ m۷߾}c[n'**jϟ2dmaaa:gϖoHĶlٲzj| 8;.X/(((((8x`DDj`ccx}ꪜdGGGkkk4'4˗/={644Yk;v߿ŋCuss{)3f O>| uwwoxͭ8ӧш̎/^֎tR~lٲtѢE .7n~C훳shh(I-՛;w?^rѢEGIJJ233^$%%2bĈu}b|||fϞj3 ___6FYY:yd]KydX-[fĈE׽{]v͘1#..0//ֶ*66g흜N<Û7oN8X53fL=:vLu֦M ,\PWWwԨQO>۷o>}"##y\Y`09^%K4c5[n.**B#";4TEEۮ]ڵkh炃mllF)++{ĉ:{C\{۷o:uj[=P~~~SLA(OEDsss9NTTԨQ|a.]N:cȴܹsu&޻w+~{n<ѐ!Cv1y/_Ժ D?444O!;4H@@q~ hD3fptt3fϟ-ڽ{78t{_vѣGȎk׮7")R__ݻTIeeƍmvU>q\?...h !ՎɓwP@Sظqlllvz޽{u֭w޳gW^iii!~!;߈WsrwwCJ~~={ h:SL0a۷>}iӦf×]t ?Vcz2dH q=4'4}Mb4~ܴRSSuttUStYfPRRsJZZzŊ7n{UNTTGzyy!;/_~4iBmx޽|o." ʕ+rvxŽ{ hS\\\l'.\())P@[>##/>|8{+BmЂ lQx#nvasN{{{yyyfqׯoケg7Ђ=x6y۶mȎM`Pd׮]'OVUUE(͒Xnݟyudڹ7pgêٳgݼys̘1ȎM8q"V &&zꤤ3kVj}[ XYYP ooo{{{ `0믙3g";4TeeeXXt=,,,BCC+++iii'O\v-Z6l0GGM6'p@@噙%&&redddddDDD^vCBUmhѢ3gv OWWήm7;f|hu%&&z{{*))X?yxx$&&_~ΝBU༼=gΜO";SB,--²8NyyyfffXX50|?5xǿx񢵾G&WbbbRR}+ã8Ο#l3f]|YOO}G~=ztʔ)RRR"""RRRGl%|biisΝ.]7k֬}?~omdGhBL&!"""##ϟwpp`29tQZZsNMM۷o Pbʔ)w9ro߾ݪкЦ߽{722ĉ#G~:u,O޽ݻd2mmm7111dG&{٪V4hPAAZ9s&33ׯ?~4h+5LLL?~۩S'yyyϽر##/yЫW?~XG]]]WWWFFFFF*KW)))UVVJJJ pȎ t={8p vիWȑ#<~_|YBB֥ϝ;w<==8q۷o .$ܺu+::ۛG5BCCm۶jժȺvW?rG9rd׮]tݻwFv˗/?{l͚5ϟX"11QWWWVV… /\|nxxxXXXkJKK'M4hРK.ݽ{wƌ/_YOO+WTUU\2<V~zxx8!dҤI!!!#F+R8p֖#ܿ?,,, rرyn۶MEEvQQs=ɓ'=zTNNZ1c^*..p«Wz(KRSS{n̓W5-|@$55577Ύܛ%Ou͚SPUV}]ɺy /S\z/u|Te~zs ѯn`k>x`ܸqQQQںu o\Brб;BS ={V__.2dHDDDócbb;wBBB/_<.33pqq!ˊK++++**j~ UTTTUUX,{Ml6DZZl2|yyj_j5Ǐ,p8EEEL& KKK !l6ھz*&&NZZ(R7P|]VVUXVVd29RzͦzR111 DGG :/USsέ64ulncǎR uAw*TUU JNN!_~.f7sw4h BȧOzZ}QWWwV1///aَ}捯CSMӧO[pU4EEEBHJJJKr<m:u*!2,,,++ᔗgffY[[BSJLLLJJk dGhCdee?ӧR EE~YXX Ȏ Ëtppppp@(eyGdGdGdGU9JXXXaLMMu&[|yv턭V=zp|Ԯզݺu5k#੫Ϟ=[+6e녰VJJJBXq g;^Zk%++lٲUdGdGdGdGdGdGdGdGdGdGdGdGdGdGdGdG@v*::ť_~bbbJJJ&Lx`kue{{{uuuաCѣG_pABgjj`0[Kw-//!jYp~aa;w [[.___ġ/[^ZjuСs |X^^vZBՂR* wl p?kCYY9..N]]]jE8g]ukC>xpРAqqqL&!j)p~ ;B+wU''={kii-]؍7.\صkW11177k׮ 65B[ ȃLj%7 U{P g~w@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@vdGdGdGdGdGdGdGdGdGdGdGdGdGdGdGf`0 7ޤdGVݾ}f2eԆ^tRUUUqqnݺ5N544/^j2$i7¨NRRܹĉcbb7Çy)++X,MMիWsm_?bN81g!OeeYBBovvݻDEEk/o߾ Ύa -f;vƍz… ӦMkdd+W9Hyݐ!C>}D??[n5Q ݺuKLL}Ύ u/{ƌwy Bŕ+WJKKj8qdiܸqcII6w޽{ !cǎ544Nnٲ^g񉉉%%%IIIdG>6yG !۷ׯ!Ν; ty5FFFFZ[[WQQ{l]v%S\={ϧNJ,,, .((+;qH i&m/_3̍7V[WBHff&]B ]UdGxرfСCO:˗'O̜92n8j)S!k׮}ayyyrrڵk !T"i,ٳ !F"tؑrD''_&5dɒW^R7WC-[ݻO>--}Rԕx!5>O {ZYfu޽"===BݣG***^z5k,xf~~KF+CCI&;vfOy9|\>>>C|B u^HYY~IoB(//AaC 4(..㊵~o>>>^GGkÆ ܋A:"V TJJZ<zoƍjjjo߾BBBwpx׹)ӂ֡|Il`` ..իnݺU[޽{cǎus玮n߿kרj֭...q Aǎ ڵkG BBBLSrr2 !bbb7nXpa׮]TTTܮ]SnDEEtbggButUTTT]]}ٲeϞ=mjjjČ5JBBBNNѣGI R')<:|n|Ϟ=-ނ@k5kP5S#GLLLܹ3ҥӣGHQRR:tݻ߿ߺS#;ȎȎȎȎȎȎȎȎ…@B]\\[߿#\#ȎȎI~#ZMb.3p8vAVKoIENDB`gWidgets/vignettes/filebrowser.png0000644000176000001440000005406011406427017017127 0ustar ripleyusersPNG  IHDRj@ pHYs᣻tIME44 IDATxyXg}p"r7WEZ@kJ9~Ƙ0Zy||ٙw}g; @ =ɹmcMwF@ }6OS\ьB@ H/xWeq hmwZ@z[`™h%:;[D!P}_MbIL~?/WDЊqpi }ZZϜ)Jՙ͌cH!Kd\)))R2\sϾj[?ޚNb : U0XDYo)HAԯeڄg\-H$52-)&4*)Jj ]ݜloB5֡pHMC۽?n<-l$(L,E#LbU}؛h=2C;Gyz,҂P2KtlϏUuH,>A(8@m‚,wjLfՎLƭ_飖ȼ[s}picg@\yJނ3U卒Maq;WBB5`&1@JNW*ik}əϛ(Cg_SC=.MKȴke]Z=`6SN^\ ļnkN7 .ﵕ;G)C8yeD2@aXV̖"'lx{2*Mc^+C]{$(f˧K%:fCwɘ)z|N)96V~߆Pt)ﱰ3".^ZS*^Qy*RvW;c'g7"P(Ǡ+9ŵǓWUm!C{!OR8EOLII)}V!fFsΜ<ɡ2kP`vs^qgH}>auQ*VvPx"F qk1:lF|UGљ9um K+Mg%RXzCi6 _5lNsse$`0Í^a4PYEDo1|5;Ȑ3Ȑ3b@#:):J9X,#2 -7#K:eoKv '7 ]^,g%&Q{D*e`Yh2@l(SӥC`z]0o3c]WV\KfvuQV٠;C+cl, &uM,%흕 |Gm9F/sZZΖ-I dJ&X\Z֣ٷYC-yݨ:3t"y@;/:Y} CNUkWJ&<.lhyTh?”hj3eOQymc OK2L0S_AxϑdD&T6{Gz2fhg OR.FCG|}+8 C#>^áݎ Ld9#͝x) WpF {aa( #+@WCI%WKq1gS%x0şxu6V/n} Cuŵ¶5u3R[޼/M4~ÇNyLͭ ;"2DR!?h]~zDkLZ'}j="ҹӄM:p]մf1~^ʂd:ΩWk04:rf_i)\JA?ѹ x\Qkۋ½|C 3~ YKCίm>wVҺ&]Q4|)^QvQzD2al@ā趚fQ^N:\:i՗!^LP! s\YgUY[9$:R!.ltYM1Ӗ <XA{M7kM&Zqv)9S-vq]HN@aėVvt4 BRՅ6=KM~p((biK$7Vd:WV˅~6C( %yŲ]ueķMPbUp dZ 6= 01h{fcti0XvUEmM@c[4ҡ/ tu)TD%DFKk_4 q`E盐e4l->k%Zbi $*%Rj_dܼi2(J hR^usM\S9aNT|5vsi㡣G"Q|V]sjf}{WoKSD%z3 %&" J LtU1 u`+q;B?SNeJr рQDD"moh}aȺB^V.ЙM(:NfEc \ksoΧͰc~c"jhAHaG|&BFӄsMmCF_}VRPZ9td[b"'R6 Ga 7 _*~SrLlt-3xxbs&!JuXM*E$VOp4rT-oz`$$]"X$[*Av]؁ M̍@ITgkYI뚠$;4kJ \ayؑvbT%3F$e?0 LsSѢѺ sItp̌_"؊fy)ZskCO,C$,4p{] 5sIHFUv櫖vܡܫ6Ffh5W~^s=Zե7(nIjk=V^~f]n3X,f5}zlh׭'eRԁx1ȕz|wi fw[XȖ 81^8<^ź0Ɉ*s0|@`Ab$]RN[nن%_n\G;*j׷XJBeCԍ&8%):F{=ضbWm <:ϔ6ZC~)PH,μ2wDb uvq") @c2Nݮkof/Õ-2tv;d6]{WػݽQJiz(M_ (u֙CsۮliTg}A^HPo,:dISSF}bwG5 #/tbML4sŧá?o& [t*ie_ƶT&OyD̆WY|N5:wH+3c}=O8G7cdE5^{]H$yO?^ctD"u635~T9H8׭&8$jA9-+c;vLe\͇KT.8 ap/awtJV^v+f)gaMee*Ɋ̭?)@SQ]w셽-8\/C6}dWƝ 1{gC `0嫜 IFG&TXv4Ȟ3&)*oN‰k$3ezP]ݺ1XE4CVHfM5k gΔm3IP߼ cfR/i6%ٲz d*S`FИzR QG; D$*W_\'P ]"x/5$3(Da:[0gJf .m$2TA"EaT`7!3uT*hTEW9Zj 6FC Ďz"UV'3u)l.S@Pzv$ Cb(t,UևDgdJَd4 ͫP*D @acT*!96;+ٙq Bpr6I˗zq1N&_|" 7*ྞi}CD pbG#I)t"r%BBhl b`y?gDs0pPP<@:RDvQ8\t CN +*]QttGK=C0@̖Hck]~SEaMQ[Ӥ/_T|~=\S[}7FYO?e K1xH֪"7PPP@ei꒼ ۖp E.L(̷]{I_^ |_+K2|A D1St Ig5Is Swyns_:2nmjksh:F:C9ƖN-6W՗?)hmE(BsYdλTwZDf_&K(Lۀ 830u)l>Inl+>J 8z–zD'R(,]2SHwNi= IDAT ^ @eQ+Ѿ?bDքHeUїr04@ 7M@ ډL?Fl;Z\ T*- y:H \G:yMi[%))㦃- y)y VȉBkB HbJe )hL!:SyTWW{{{WWWCg @ … mmmЙB HYYY,X~8S3w\]5]- ˬ^ϯ^ZM4@ Ϛ5 6$wٶm۶m4߷[l4#{Ն@}˙xUVurʕ jmmuO81n8}}}ӧ榧O6pܹ>cƌvvvG7ٳgc|>)**JeĉǏ744w3JjkKA3}w477>}ZY''}S;vشiSQQQNNWXXغuT3ޏ?,'N H+Wz'ݻ|A5880tЫW7sվsnݺ߾enn`kRlllmV__ޞ;_7|) [[[/]?ZZZ.^hjj/]tժUnReV2ϟdɒѣGwZ 3]t dZr% 4(<cƌFr*((_JFzzzzz… e)~RL"Kx|ZZp 's骬ѣG+A/K?Cy͛7o<)}{KJYKA1pn@3@ L!:S@g @ ЙB H_CqiTﲮ~F7lYݙ ^.gq@g T@ n_8f @ Z:S@3@ L_ɓHל9s@g=b%D"QaaŋN< m @3Ոinn.--5jԱcǼ5O===y<@ӛ5kVJJoBt79sLl٣o.V"ٳŅd33 dddh rFeQCiJ(jlllٲn5o)7TгgϺ{yyz<?qDl@@Ν;7lPQQQQQcǎe˖K *+섥1 z-6000%%eϞ=---ϟwrrZ|fɓ'O4)..NQb=5P(LMM-))/BiȿWUc[?J{ @,׿N]]]qqƍNmZ[[7o,JO555YYY%&&tT k"bTouqqIOOOKKsuuդz{7jRV!`t[,M@muVî8vva/ T"T*e01NR_o(BzHH`ׯmA'KK,EZ;="//nر555=: w'A!ׯ_3fLWg333=<<=<xPV@n%3?U_vȑ/_ӕ/^8b􀀀ӧOkXo(@ lܸ… ﬏+j:3gFEEmݺU>Qy 蚚[HLq8BoKÐaҥ}]{{B?Xx~*o P;tЊ+|O.[L$ɧTTTpwЮ555 S)))G*EO۷#F('"STtSN=zso޼Ϝ9sԨQcƌIIIiiiiiiIII3f̸q<==U 4hŋWX]{HlDD3gZZZۯ\*bX %{0o޼x𠠠GVUU蠠pB"Zg*>}򗔕 V;wnʔ):::( 3g>|xĈT*J9~SQ$ >hTeb^gjj(pqq|7LҔ\zיJҒk׼tttxk״ uGw|mcK"B '~GFF\'%%JR,7GFMFFFggJO (//m@+q@g @ ЙB D4115|@3+! /^( բ&QF;vرc&Mꪬ[ E 888|ƍS 1D"9|p\\ܣGGg9R3--njhhp8#G;vL,ӦM hJ*dP522O/_|VVرc~!`Ȑ!~~~s̑iӦEGG+[FWj,#p= ?ޘjZAC죉2HO@gLeeehhg}}}YPXQQqʕ5kָm߾$$$ӧ[npEEE/^\vl͛7߿Fڵk֬Y@X\XX~_~+D"/_.֬Y#z~z7lpl_5kVOKSN}g݊֘=VGC!LRs^^^nn4,E"LLL>3fL8ɓ}"111fϱ_d2Kqpp_w)/[XX޽APq޽k֬Ν;wʕ4ƍ9rq㒓e-[M6fٖoNLLLXXT*ݸq&T1hy6_"T*e01N(rnsr7ntuVyR˗/R~+nZfC.pՇxUVi9ѣG>~ Hw'AaM6SKvvvٶm۶xbOOM6ʟruuVX,.(( 6s^^@ Bܹ榜&یǧE[u111?~LL-#C t=466M !'޿?===;; :ty<AVb˗dD_}'|`^*nhhPHܾ}>@ r"dcǏ_nW#J1Aw]=GEC:J$aXWW'YqS eԩk֬9tPNNe˰S,Ka)<~GHJJr~~~=ꌳX,Q@ ##lk Qi . >\GG;>|xZZZS}+ CO )֝]^~СC{Z@ ZXX`NNNW^R_Fyzzy|n{m{{+W̜9S!ʕ+ϟ??eʔ7'&&ʶE&L1*Ozt:>p8Ag~s5*k֬D)nE~'PPj׮]ʢL{k lٲMl秜Aݻwv嬚ҥKEEEQ_|(I9NKKS+g*HD"TGGGiiillLj#4Yty''' ׯ/\;;~ &L2%%%Q(޾}oÆ *9sFV1bĴi.^zElTW/2/X 44w58qbL&SaaҤIG75kBCC?^]]-kjjBCC5_|T obl2L& GG͛7˿mHNN>rի={F&Ν+˶n:466bo@uZkٳg]vlܸQŋ߀Rfɒ%'N]uƍΝn:lݨJ{vk̷:#o|WW۷]b9;; >(d;AoG6{Z$UTT'E?rd222rʕ%%%JR,7GZd٩ғ˭`A Wǖ-[ݻBsC Lձpw6G@ }}@3@ L!&[ҧ{02@ ͇@ L!:SMgzIkE;[H$¾FuIhkF4NsssiiQ;>>} A=2`h4ss9s$''+Tڵk b^jdd /Vlcc#{քT@"ٳŅd33 dddmt/%EQcce˖577w򝠡2{L ={{0 j2`^paɁ_|ryAttyϝ;7**JOOnE?;yI&i"*000%%eϞ=---ϟwrrZ|j,E((cO/@3J,RD"aqӭ[222;>En?gΜm0QQQ?zB!˖-|JxKKC>}>L_twb01]>d CusݻoǭWWW7vXGu[DGGG֩nKp9Sٓцzknn|ݻfCȑ#1116m:vu-Zh"M}͝;}ݺu@OX߿{ L5w5nջh644;ͮ%lŋ?ccъ*/V,?~| bzQӦM+.. BQٳF4iREE&(ZZZfff߿M.N@AId![%J311YbE``&kkklJϮ󋊊8PYY_VTyIII...ءP3fƖY[[kb^k/ tE/i/j2)k" DdK.mjj}X-66Vi(aƍ.\x3gFEEmݺU>N!gMM -G8N&! ZbC%OKKˆ 䣧\ ]jUlךz.%%EɲeD"|JEEoӧ(zmpĈqtrr3|n!T9&ud 4hŋWX|ȑ#Ç5jԜ9sq/R6vڋ/vbXl6WS0""̙3---W\|e2o޼x𠠠GVUU蠠pBdbMsss"VAlǹsvܩ0qr^lv@"۷pBoMO9jtUGGǥKl>jժkתO?nmmM"?n@z6)"h~P㓒R[[ [Kݺ:U[[+;ih4JU QCq wL5'--{P [Y>>>=9996l|bvv.?IUZKŅׯ _z'n 2224Rw"Bz_ϖ~WBmۦm۶`Noؽ{zȻv'OܟVE8H ֡6V;^?OH#?d޼yُ=?ݛ;w|ϻw'e[jժU jmmw/܆A oL5 XҞ䋗/]={t#8U^^NPsX$NOuA>CGG罻|||Ԍsυ ())u֮]3l߾=""bԩ[[ۃb*mٲi˖-˗{]CÔ}\=D;)ҥKwNLLTISյO<)^ <z;wv$ۖ˾3w\Yw~>JZUUղelllx<566509r#))OhǙ^t飏>_5jƭŋ ;To־v.sΝ[ny{{+H$pB:~鲲ڊF􌈈ؽ{|vt:hәjIE+6T+$IDATǤenK!rʏ>h8zw޿ׯ_777'H g1SLAQ޽{ءSZZB4GGGMg'>+kQy67qXhDazɌ3Oeff K. \rEޟl߾=))) ϙ3g׬YzjX\SSf5g}‚v4(˼IX-6lظq֭[SILkk|ׯ={gbFGG'$$92!!!&&UY=D]z; dQxT%=}! @ޑ|ȕ+W*++JyՊ*&Lv!)@g @ ЙB :S@-p8"F Kad @ @ ЙB t7ɓ'}T @3UX HTXXxE//'OB[C L5uKKKGu1ooo) 3gT.؈}Q!۴iTJ6mL;%Hd2 |ӦMb[0===y<@ӛ5kEezz!j,RvPg5(/[[ 5iM݃U镕Ϟ=swwRT;g5ybcc'O,J-Z$޽{wqppO{l t ,++۳gϐ!Cx|AAAjj333 D۷o睝hvܹ 6DGG{'NĤ F7C/SWFA,?~x_|ѣGrHƎ/85꺺:ioש+..޸qԩy<v뫑PQQaiiYYY.⒞ꪐm޽fRw^5:PԦ&5޽{ظ[Z[[m޼Y2=5j,vxC=R FuiҚH{֭[{[:i`-G 2=Z}Y>dɒǏ̐WWW7vX@MMͣG,--eg.\O?=x`Ȑ!n݊/\GG'##cҤI\!C={֭V?7|KvHHȻUo7n ;\v3= qD"Ѱ;6o޼fdEEEE)|7,~ %To߾s纻[.::@M\}}n~1cBB,Ím /Zs TrRSS?~| g0_|/**y,ȝ)iӦ(zQFM4BH$\` ժ^5R&S[;hwG6eii7p8sVGD",]C!&&&+V Tvqquuu]\\~e˖kע(+xy*:cƌز2kkkL&̚5+,,[l(Q׿d2!XL%-555 7p8)C5{ӧXO<'N:U>?駟233oܸk!7n\zFyYf[}|M,S; t̙3xU.\(KSkjj |n!?2p ^ :thŊuuuG(55^a.%%Ea@AofҤI!!!8\nٲe"H>B>jt]?UsQ}6v8b8:99>~L%H$:>ikРA/^bvblOO]={vjpvv>sLKKK{{+W|||,YHZMw\CCC{{͛7}||l~,v"͋ :zhUUX, -@sdbYrÇHlWSW^utt\t)V Xv~tZmڴヒ077g0ӧOހosDTޭϧ~qkkkdeeu77w 32pj_[XK)"***dNS @sA)))>>>ø4);ӦM h42rkkkUU WY=UyWFFF|s*џԃ@Ed X`I|RV/HIdү>T5Uxݻ`h>nU~LOO/_漡U'y;.Ճ@4Q.]ڽ{wbbzO "}RXIEuj`GHJJ漡U OWю3tc_͸x"aG mmk슋S/FyzzFDD޽6PiU&۔Q=tMg'XRbU4\|:eEݻ[H(X)--M!OZZ#T)L5gTy67qXhDa<>>>gΜE䭺f???H4n8S__믿B E=zE85 2odehb̞=ٳU]]]\\\F*U⿬d;RwR%UIO_0@{iz~ )%s[% 28܈٠m#@& t60h}!SAt@"PtRR&Pt}qJ|?{ν99G9 0E97P[ѧk[;)k׮ŅTa> LS@ L-0a 0)`&i]]݄vTYY1SYY9͙ |wbb}YW׎YgR"L׬Y>O+++ޮ뗯߸t\ L4OM&dgϞ{nBBeѬWMVfRL݋@ 3MOnOX 9uTdd主xK,_x1Yyba&L !,秺wlpCþ˗2~2GQV~aEh4+:y+\]]_|łf}BB ?#pY*faaatu2tSr9:.Kpe4Ns- O)LMM길vP8{"e2Ybb"!~? y^EcyfNO:HQ5*eKo0z[މ-^^^6}Wرc6m]\\JJJBBB^{5믿f٫l694os !uuu2󎓔B8O4ڮIJVkM088XZZ˙?k*g1;Y`R=q… g mL8'L_{GC}XYo}KÇ#Ҿsr)h4 "99yh쓔k09ھ\jS]ic?-mذz}xxxffT*? -[E[n ްalٲm۶amիKKKJҥKJeYYիS4oő)G?Y#<3 :,ob̛ryhh(˭ k[;) 8)a S)[f8@ La 0n5>$$Μ9c墢GyZ-Fh^WjR)0'4(ӼyS֭+//gtz@ᘚT"e6Ӈ^CQTwwwFFFrr&<SBH\\\aa!<DC2]\xF IOT2WIx/rnn+<9Ӓz6; ߧƸcc]4Gcޗ9C,ڱcV\PXXh^TXXO) ӧO[^^^~~~Gň:f4<|lsݟ#?\B8BMcco|6徾---7o6fgg~~~---nnnф_~%55 o@9zzz|M4`Ô;v[NV9HQ5*eKo0z["y̕+WB[PH8p +++00)ڻw/YYYYYY^z饼<4.\4瞦̓Y(((M5cq´.77qBܾFπں[ݯmmm믿noo7Uhh7߭o:\t:]mmmRRRUUUllD7̓ى=UUU+1>! MbfafGv}WTTzsssWZjsA&QORBȝ;;?1X3ԽB]mlld>>> ˖-/^(]F/XԩOyN SIJ\4O#m۷oOMMzhSSD"abD"QTLі-[袔DrŬ{D"QEE;--M**JFCQT___QQT*MKKC&9SwӺ;{ >oMEQgǽ7:LK !QQQj^HJJJNNfbqooΝ;Oݛ~EbD BP*B ž}v~zժUG `Oi g}MMLa 8O"L&M] Dbtw̆T\p>!uo/$taz `TG5>IENDB`gWidgets/vignettes/gWidgetsImplementatations.xls0000644000176000001440000045400011406427017022017 0ustar ripleyusersࡱ; )d  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcghijklmnopqrstuvwxyz{|}~Root Entry  \pCalc Ba=@=@ 8"1Arial1Arial1Arial1Arial1Arial GENERAL"TRUE";"TRUE";"FALSE"                + ) , *    ( (\   H(\  H H  H (  H (T `Sheet1Sheet2lSheet3jb( 3  @@  asvaluesvalue<-[[<-lengthdimnamesnames<-dimnamestagtag<-size<-update enabled<-changedclicked doubleclick rightclick keystrokeexpose unrealizedestroy Basic WidgetsGet selected valueSet selected valueExtract from available valuesSet Available valuesLength of available valuesDim for available valuesNames of available valuesSet data for objectRetrieve data for objectsDefault handlerHandler for click eventHandler for double click eventHandle right mouse buttonEach keystrokeWhen widget is exposedWhen widget is unrealizedWhen widget is destroyedgbuttonA button widgettextbutton text (or icon)Rgtk2rJavatcltkOK gcalendarA calendar widgetget dateset databad hack gcheckboxCheckbox for TRUE or FALSEGet value as logical Set value Get label Set labelgcheckboxgroupA group of checkboxes)return values; index=TRUE returns indices??How is this set? Get labels Set labels Get Labels Set LabelsgdfEdit a data frame double-click put on row opens editing??? needs extension gdroplist/Popup selections, editable=TRUE gives combo boxget selected valuesget all valueslength of valuesHACKgeditOne line text entryget textset texttype ahead valuesset typeahead valueslength of type ahead values ggraphicsGraphics device??? tkrplot limitinggimageView image, icons Get filename Set filenameOK, pnm and gif onlyglabelA label widget OK, no markupgmenuA menubar widget; list->menu return list set from list list elementsset list elementsgradioA radio group widget selected item Set selected label names set names gseparatorA horizontal or vertical linegsliderSelect by sliding value Get selectedOK, integer selection only gspinbuttonPush buttons to select numeric gstatusbarShow status in bottom of windowgtableSelect/View tabular dataHACK, use only one columngtextMulti-line text widget-OK, dynamically expanding size? (others too!)gtoolbarA toolbar widgetlistset listget list partsset list partslength of listgtreeA tree widget showing tablesselected value list partsDIALOGS'Dialogs have no methods, they are modalgmessage'Simple message with dismiss type buttongconfirm$Simple message with Yes or No optionginput;Simple message with available text input and Yes/No optionsgdialogs#Shows widget with yes or no options"??? needs container to pass widgetgfileFile selectionCompound Widgets gcommandlineA simple command lineownggenericwidgetA list to widget makerghelp A help viewer ghelpbrowser!Package specific Compound widgets gdfnotebook'A notebook to hold editable data framesNo dfggraphicsnotebookA notebook for graphic devicesUses non API codeno embeddable graphics deviceNo graphics device gvarbrowserShow variables in global env.0Should get and set up knowntypes, and the filter uses tree no tree, hack Containers gexpandgroupHas means to hide/unhidegframeGroup with labelggroupA group container, like a boxOK, no use.scrollbars addSpringPush widgets to right or bottomaddSpaceAdd fixed space (pixel counts)glayoutTabular layout of widgets"data frame notation for placementsNeed to use layout as container gnotebook gpanedgroupTwo panes with sliding dividergwindowTop level windowtitle set title    dMbP?_%*+&C&"DejaVu Sans,Book"&A&C&"DejaVu Sans,Book"Page &P&333333?'333333?(ffffff?)ffffff?"d,,333333?333333?U } 0}  aaa a a a  aaaaaaaaaaaaaaa                                            ! " # $ % & '  ( ) * +  ` ,` -` . /` 0 1 2 3` , ` - ` . 4 ` 5 6  7 8  9 : `  , ` -` . /` ; < = > ? @   A  B ` ,` -` . /` C D` ,$ E F G` -` . H` I J K  L L M` ,` -` . N` O P Q R S T U` ,` -` .` !a"a#a$%a&a'a()a*a+a,-a.a/a01a2a3a45a6a7a89a:a;a<=a>a?a V W `  !,!` "-"` #. #X#` $Y $Z $[ $\$`$ %,%` &-&` '. ']'` (^ (_ (Q (R(`( ),)` *-*` +. +`+` ,a ,b ,c ,d ,e ,f,`, -,-` .-.` /. ///` 0g 0h 0i 0j 0k 0l0`0 1,1` 2-2` 3. 3/3` 4m 4n4`4 5,5` 6-6` 7. 7/7` 8o 8p 8q 8j8`8 9,9` :-:` ;. ;r;` <s <t < <j<`< =,=` >->` ?. ?N?`@AaBaCaDEaFaGaHIaJaKaLMaNaOaPQaRaSaTaUaVWaXaYaZ[a\a]a^_a @u @v@`@ A,A` B-B` C. CNC` Dw DxD`D E,E` F-F` G. GyG` Hz H{ HQ HRH`H I,I` J-J` K. K|K` L} L~ L L L L LL`L M,M` N-N` O. ONO` P P P P PP`P Q,Q` R-R` S. SHS`T` U UU` V V:VV W,W` X-X` Y. Y/Y` Z Z:ZZ [,[` \-\` ]. ]/]` ^ ^:^^ _,_``aaabcadaeafgahaiajakalmanaoarsatauaxyaza{|}~ `-`` a. a/a` b b:bb c,c` d-d` e. ee` f f:ff g,g` h-h` i. i/i`j` kk` l l:ll m, mm` n-n` o. o/o` r r:rr s,s` t-t` u. u/u` x x:xx y, yy` z-z` {. {/:{<| } }<}} ~, ~:~ -<aaaaaaa} .<: ::  : ,` -` . `:  : , ` - ` . ``    4 , : -: . :< :  : ,: -: . /:  : ,: -: . N:  : ,: -: . :  : ,: -: . /:  : ,: -: . /:    2 ,: -: . /  2 : ,: -: . /:   : ,: -: . :    6 ,: -: . /::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::     :::::::::: : : : : :::::::::::PH0(  >@A    dMbP?_%*+&C&"DejaVu Sans,Book"&A&C&"DejaVu Sans,Book"Page &P&333333?'333333?(ffffff?)ffffff?"d,,333333?333333?U }  PH 0(  >@   dMbP?_%*+&C&"DejaVu Sans,Book"&A&C&"DejaVu Sans,Book"Page &P&333333?'333333?(ffffff?)ffffff?"d,,333333?333333?U }  PH0 0(   >@<d  FMicrosoft Excel 97-TabelleBiff8՜.+,D՜.+,\Oh+'0 PXp  John Verzani John Verzani19@@!@Q7j@rG(sss}}}```yyyaaaqqq}}}fffֿȜvvvuuu}}}sssIIIvvvqqqKKKooo[[[ZZZcccpppqqqKKK[[[kkkSSSsssvvvqqqKKKSSSsssppp666sssoooSSSRRRsssOOOoooooofffnnnLLLKKKLLLHHHooo[[[LLLHHH[[[^^^oooLLLHHHooocccooooooSSSoooOOOggglll888||||||LLL;;;[[[ͽ|||LLL666ooo|||LLLooo888vvvooo;;;UUUoooҜ~~~uuutttkkkkkkߔjjjߏfffvvvqqq}}}~~~666fff}}}fff叏FFF돏~~~mmmwww{{{nnn{{{UUU옘sss}}}```yyyaaaqqq}}}fffֿȜvvvuuuvvvuuuZZZvvvuuuZZZ}}}sssIII|||ccc[[[$$$nnn|||cccSSS000sssjjj~~~jjjyyygggfffMMMsssIIISSS~~~jjjyyytttyyyQQQWWWqqqjjjDDDΈ}}}sssIIISSS|||jjjyyytttyyyQQQWWWqqqjjj~~~jjjyyyooo|||ccc777OOOuuunnn|||ccc222000sssjjj~~~jjjyyygggfffuuunnngggTTTpppLLLKKKNNN[[[NNNSSS!!!QQQIIILLLJJJIIIKKKSSSLLLJJJWWWOOOWWWIII[[[%%%LLLKKKSSSFFFJJJWWWOOOWWWIIILLLJJJoooNNNOOOOOO@@@NNNHHH!!!QQQIIILLLJJJ@@@wwwWWWSSSeee|||mmm[[[~~~tttmmmSSS@@@~~~kkk“|||zzzkkkœ~~~===jjj|||```kkkœ~~~kkk;;;mmmIII~~~tttmmmCCC@@@~~~kkk“ttt䫫xxxmmmഴ      !"#$%&'(*fffߊTTTVVVmmmUUUNNNWWW[[[ZZZ廻PPPUUUrrrpppNNN???^^^yyyaaaaaarrrம̣nnngggؖfffߊTTTnnn{{{VVVqqqοmmmUUUNNN???\\\ZZZ廻ٹ옘Ջߔjjjߏfffvvvqqq}}}~~~666fff}}}fff叏FFF돏~~~mmmwww{{{nnn{{{UUU옘sss}}}```yyyaaaqqq}}}fffֿȜvvvuuu}}}sssIII|||ccc[[[$$$nnn|||cccSSS000sssjjj~~~jjjyyygggfffRRRCCCRRROOOuuunnn|||ccc222VVVsssjjj~~~jjj111fffooonnnjjjyyySSSGGG[[[cccrrrPPP<< 1) { secondArg = names(lst)[2] if(secondArg == "y") { variableType = "bivariate" lst[['x']] <- NULL lst[['y']] <- NULL } else { variableType = "univariate" lst[['x']] <- NULL } } } ## make list as a string out = Paste(fName,".LIST <- list(", "\n") out = Paste(out, "\ttitle = \"",fName,"\",\n") out = Paste(out, "\thelp = \"",help,"\",\n") out = Paste(out, "\tvariableType = \"",variableType,"\",\n") out = Paste(out, "\tassignto = ","TRUE",",\n") # out = Paste(out, "\taction = list\(\n") out = Paste(out, "\taction = list(\n") out = Paste(out, "\t\tbeginning = \"",fName,"(\", \n") out = Paste(out, "\t\tending = \")\"),\n") # out = Paste(out, "\targuments = list\(\n") out = Paste(out, "\targuments = list(\n") # out = Paste(out, "\t\tArguments = list\(\n") # add or change these for(i in names(lst)) { ## intercept the type name = i val = lst[[i]] type = str1(lst[[i]])$type # cat(f,":",i,"is of type",type,"\n") if(0) { ### want to test for empty ## what do do here - out = Paste(out,"\t\t\t\"","...",'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\ttext=",'""' ,"),\n") } else { ## these vals we handle generically val1 = "placeholder" switch(type, "name" = { out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\ttext=", '""' ,"),\n") }, "numeric" = { out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\tcoerce.with= as.numeric,\n") out = Paste(out,"\t\t\t\ttext=\"", val ,"\"),\n") }, "logical" ={ out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gdroplist\",\n") out = Paste(out,"\t\t\t\tindex= FALSE,\n") if(!is.na(val) && !is.null(val) && is.logical(val) && val == FALSE) { out = Paste(out,"\t\t\t\titems=", 'c(\"FALSE\", \"TRUE\"),', "coerce.with=as.logical),\n") } else { out = Paste(out,"\t\t\t\titems=", 'c(\"TRUE\",\"FALSE\"),', "coerce.with=as.logical),\n") } }, "character" = { out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\tcoerce.with= as.character,\n") out = Paste(out,"\t\t\t\ttext=\"\'", val ,"\'\"),\n") }, "call" = { ## only handle c(...) ## others are just blank gentry callVal = as.character(val) if(callVal[1] == "c") { items = eval(val) quoteIt = '\"' if(class(items) == "numeric") quoteIt = "" ## combin # theValue = "c(" # for(j in 2:length(callVal)) { # theValue=Paste(theValue, quoteIt,callVal[j],quoteIt, ',') # } # theValue=Paste(theValue,'"")') #add emput tmp = paste(quoteIt, items, quoteIt, sep = "", collapse=", ") theValue = paste("c(", tmp, ")",sep="") out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") if(length(callVal) >3) { out = Paste(out,"\t\t\t\ttype= \"gdroplist\",\n") if(class(items) == "character") out = Paste(out,"\t\t\t\tdo.quote= TRUE,\n") } else { out = Paste(out,"\t\t\t\ttype= \"gradio\",\n") out = Paste(out,"\t\t\t\tindex= FALSE,\n") } out = Paste(out,"\t\t\t\titems=", theValue ,"),\n") } else { ## just leavl blank out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\ttext=\"\"),\n") } }, "NULL" = { out = Paste(out,"\t\t\t\"",name,'"',"=list(\n") out = Paste(out,"\t\t\t\ttype= \"gedit\",\n") out = Paste(out,"\t\t\t\ttext=", "\"NULL\"" ,"),\n") }, # default { out = Paste(out,"Don't know what to do\n") }) } } ## finish up out = gsub(",\n$","",out) out = Paste(out, "))\n") # trimmed a ) for Arguments return(out) } gWidgets/R/dialogs.R0000644000176000001440000001344311643047474014044 0ustar ripleyusers##' @include guiComponents ##' Alert dialog to display transient messages ##' ##' @param message main message. ##' @param title Title (may not be displayed) ##' @param delay length of time (in seconds) to display ##' @param parent parent object to show near ##' @param ... ignored ##' @param toolkit toolkit ##' @rdname gWidgets-dialogs galert = function( message, title = "message", delay = 3, parent = NULL, ..., toolkit=guiToolkit()) { .galert(toolkit,message, title, delay=delay, parent=parent, ...) } ##' generic for toolkit dispatch ##' @alias galert setGeneric(".galert", function(toolkit, message, title="message", delay=3, parent=NULL, ...) standardGeneric(".galert")) ##' Constructor for modal message dialog ##' ##' @export ##' @param message Character. message to display. ##' @param title Character. Title ##' @param icon What icon to show ##' @param parent Hint as to where to display ##' @param handler called if Ok button clicked ##' @param action passed to handler ##' @param ... ignored ##' @param toolkit toolkit ##' @rdname gWidgets-dialogs gmessage = function( message, title = "message", icon = c("info", "warning", "error", "question"), parent=NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) { .gmessage(toolkit,message, title, icon, parent, handler, action, ...) } ##' generic for toolkit dispatch ##' @alias gmessage setGeneric(".gmessage", function(toolkit, message="", title="", icon="", parent = NULL, handler=NULL, action=NULL, ...) standardGeneric(".gmessage")) ############## ginput #################################### ##' Constructor for modal dialog to collect a line of text ##' ##' @export ##' @param message Character. Message to display. ##' @param text Character. Initial text ##' @param title Character. Title of window ##' @param icon which icon to display ##' @param parent gives hint as to where to place dialog ##' @param handler called on \code{Ok} ##' @param action passed to handler ##' @param ... ignored ##' @param toolkit toolkit ##' @rdname gWidgets-dialog ginput <- function( message, text="", title = "Input", icon = c("info", "warning", "error", "question"), parent = NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) { .ginput(toolkit, message, text=text, title=title, icon, parent, handler, action, ...) } ##' generic for toolkit dispatch ##' @alias ginput ##' @export ##' @rdname gWidgets-dialog setGeneric(".ginput", function(toolkit, message=message, text=text, title=title, icon=icon, parent = parent, handler=handler, action=action, ...) standardGeneric(".ginput")) ################# gconfirm ################################# ##' Constructor for modal dialog to get confirmation ##' ##' @export gconfirm = function( message, title = "Confirm", icon = c("info", "warning", "error", "question"), parent=NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) { .gconfirm(toolkit,message=message, icon=icon, parent=parent, handler=handler, action=action, ...) } ##' generic for toolkit dispatch ##' @alias gconfirm setGeneric(".gconfirm", function(toolkit, message=message, title=title, icon=icon, parent = parent, handler=handler, action=action, ...) standardGeneric(".gconfirm")) ################# gbasicdialog ################################# ## define subclass for basic dialog setClass("guiDialog", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' Constructor for modal dialog that can contain an arbitrary widget ##' ##' The basic dialog is basically a modal window. To use there is a 3 ##' step process: 1) Create a container by calling this constructor, ##' say \code{dlg}; 2) use \code{dlg} as a container for your ##' subsequent GUI; 3) set the dialog to be modal by calling ##' \code{visible(dlg, set=TRUE)}. (One can't call \code{visible(dlg) ##' <- TRUE}.) ##' ##' @export ##' @param title title for window ##' @param widget widget to add (Only if toolkit supports it) ##' @param parent parent to display by ##' @param do.buttons FALSE to suppress buttons when no parent ##' @param handler handler called when \code{Ok} button invoked ##' @param action passed to handler ##' @param ... ignored ##' @param toolkit toolkit ##' @rdname gWidgets-dialogs gbasicdialog <- function( title = "Dialog", widget, parent = NULL, do.buttons=TRUE, handler = NULL, action = NULL, ..., toolkit=guiToolkit()) { if(missing(widget)) { obj <- .gbasicdialognoparent(toolkit, title, parent, handler, action, ..., do.buttons=do.buttons) obj <- new( 'guiDialog',widget=obj,toolkit=toolkit) } else { obj <- .gbasicdialog(toolkit, title=title, widget=widget,parent=parent, handler=handler, action=action, ...) } return(obj) } ##' generic for toolkit dispatch ##' ##' @alias gbasicdialog setGeneric(".gbasicdialog", function(toolkit, title = "Dialog", widget, parent, handler = NULL, action = NULL, ...) standardGeneric(".gbasicdialog")) ##' generic for toolkit dispatch when there is no parent ##' ##' @alias gbasicdialog setGeneric(".gbasicdialognoparent", function(toolkit, title = "Dialog", parent, handler = NULL, action = NULL, ...) standardGeneric(".gbasicdialognoparent")) gWidgets/R/gtoolbar.R0000644000176000001440000000166311436225344014226 0ustar ripleyusers##' @include guiComponents.R ##' A toolbar class setClass("gToolbar", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' A toolbar constructor ##' ##' @exports gtoolbar <- function( toolbarlist, style = c("both", "icons", "text", "both-horiz"), action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gtoolbar (toolkit, toolbarlist=toolbarlist, style=style, action=action, container=container ,... ) obj <- new( 'gToolbar',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gtoolbar setGeneric( '.gtoolbar' , function(toolkit, toolbarlist, style = c("both", "icons", "text", "both-horiz"), action = NULL, container = NULL, ... ) standardGeneric( '.gtoolbar' )) gWidgets/R/gtree.R0000644000176000001440000000312511472110136013506 0ustar ripleyusers##' @include guiComponents.R ##' class to display heiarchical data in a tree widget setClass("gTree", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for widget to display heirarchical data ##' ##' @exports gtree <- function( offspring = NULL, hasOffspring = NULL, offspring.data = NULL, col.types = NULL, icon.FUN = NULL, chosencol = 1, multiple = FALSE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gtree (toolkit, offspring=offspring, hasOffspring=hasOffspring, offspring.data=offspring.data, col.types=col.types, icon.FUN=icon.FUN, chosencol=chosencol, multiple=multiple, handler=handler, action=action, container=container ,... ) obj <- new( 'gTree',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gtree setGeneric( '.gtree' , function(toolkit, offspring = NULL, hasOffspring = NULL, offspring.data = NULL, col.types = NULL, icon.FUN = NULL, chosencol = 1, multiple = FALSE, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gtree' )) ## methods ##' svalue get selected values. index=TRUE: 1-based path; index=FALSE|NULL chararacter value ##' svalue<- set path by index ##' [ get text based path (by ids) ##' update update tree at root gWidgets/R/glabel.R0000644000176000001440000000461512034653063013641 0ustar ripleyusers##' @include guiComponents.R ##' Label class setClass("gLabel", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for label widget ##' ##' @param text character. Text for label. Coerced to character and pasted together with newlines ##' @param markup logical. For some toolkits, one can specify marked up text. ##' @param editable logical. For some toolkits, label can be edited ##' when this is \code{TRUE}. Generally found to be an unexpected ##' interface for users, so use is discouraged. ##' @param handler function. For some toolkits, this handler will be ##' called when the label is clicked on. In general, labels are ##' expected to be static objects so this use is discouraged. ##' @param action passed to \code{handler}, when called ##' @param container parent container ##' @param ... generally ignored ##' @param toolkit underlying toolkit. Usually not specified ##' @return \code{gLabel} object to manipulate and creates widget on screen ##' @export ##' @examples ##' w <- gwindow() ##' g <- ggroup(container=w, horizontal=FALSE) ##' l1 <- glabel("Some label", container=g) ##' l2 <- glabel(c("pasted with", "new lines"), container=g) ##' svalue(l1) <- "New text for some label") ##' svalue(l1) glabel = function( text= "", markup = FALSE, editable = FALSE, handler = NULL, action = NULL, container = NULL, ..., toolkit=guiToolkit()) { ## collapse if more than one line text <- paste(text, collapse="\n") widget = .glabel(toolkit, text= text, markup = markup, editable = editable, handler = handler, action = action, container = container, ...) obj = new("gLabel",widget=widget,toolkit=toolkit) return(obj) } ##' glabel generic for toolkit setGeneric(".glabel",function(toolkit, text= "", markup = FALSE, editable = FALSE, handler = NULL, action = NULL, container = NULL, ...) standardGeneric(".glabel")) ##' svalue<- generic ##' ##' Ensure value is character vector. Pastes values together by collapsing with a new line. ##' @use_svalue_otherwise setReplaceMethod("svalue",signature(obj="gLabel"), function(obj, index=NULL, ...,value) { ## enforce that value is character value <- paste(as.character(value), collapse="\n") callNextMethod() }) gWidgets/R/gcalendar.R0000644000176000001440000000445611511470436014336 0ustar ripleyusers##' @include guiComponents.R ##' a calendar class for date selection setClass("gCalendar", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' A constructor for a date selection widget ##' ##' @param text initial text ##' @param format Date format ##' @param handler handler called when changed ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to \code{add} method of parent ##' @param toolkit toolkit ##' @return Returns an object of class \code{gCalendar} for which the following methods are overridden: ##' \enumerate{ ##' \item \code{svalue} get the date ##' ##' \item \code{svalue<-} set the date ##' } ##' The change handler is inherited from \code{\link{gedit}} ##' @export gcalendar <- function( text = "", format = "%Y-%m-%d", handler = NULL, action=NULL, container = NULL,..., toolkit=guiToolkit()){ widget <- .gcalendar (toolkit, text=text, format=format, handler=handler,action=action, container=container , ... ) obj <- new( 'gCalendar',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gcalendar setGeneric( '.gcalendar' , function(toolkit, text = "", format = "%Y-%m-%d", handler=NULL, action=NULL, container = NULL, ... ) standardGeneric( '.gcalendar' )) ##' svalue method for gcalendar ##' ##' Main property of calendar is the date ##' @param obj object ##' @param index ignored ##' @param drop ignored ##' @return character. The date, after formatting. ##' @exports setMethod("svalue", signature(obj="gCalendar"), function(obj, index=NULL, drop=NULL, ... ) { .svalue(obj@widget, obj@toolkit, ...,index=index, drop=drop) }) ##' set date ##' ##' @param obj ##' @param index ignored ##' @param ... ignored ##' @param value character. Should be in format for calendar widget ##' @return void ##' @exports setReplaceMethod("svalue", signature(obj="gCalendar"), function(obj, index=NULL, ...,value) { .svalue(obj@widget, obj@toolkit, index=index, ...) <- value return(obj) }) gWidgets/R/zzz.R0000644000176000001440000000360611731167502013250 0ustar ripleyusers##' function to bypass call to require to keep things quiet ##' ##' @param package name ##' @return result of call to require(pkg) .bypassRequire <- function(pkg) { do.call(sprintf("%s", "require"), list(pkg)) } ## needed to find methods .onLoad <- function(lib, pkg) { ## ## Bad practice here (see ?.onAttach), but don't want to require tcltk although likely it isn't too much to ask for ## doRequire <- function(pkg) do.call("require",list(pkg)) ## popup <- function() { ## ## popup install message if not presnet ## ## already checked that no gWidgetsXXX is available ## all <- utils:::installed.packages() ## pkgs <- rownames(all) ## title <- "gWidgets needs a toolkit package" ## msg <- "gWidgets needs a toolkit package installed." ## if("tcltk" %in% pkgs) { ## if("RGtk2" %in% pkgs) { ## msg <- paste(msg, "Try installing gWidgetsRGtk2.", sep="\n") ## } else { ## msg <- paste(msg, "Try installing gWidgetstcltk.", sep="\n") ## } ## installing_gWidgets_toolkits() ## doRequire("tcltk") ## w <- tktoplevel() ## tkdialog(w, title,msg,"",0,"close") ## } else { ## msg <- paste(msg, ## "You must install either RGtk2 or tcltk,", ## "then a toolkit package.", ## sep="\n") ## packageStartupMessage(msg, "\n") ## installing_gWidgets_toolkits() ## } ## } ## ## check that a toolkit package is loaded ## # tmp = installed.packages() ## # choices = tmp[grep("^gWidgets.",tmp[,1]),1] ## # if(length(choices) == 0) { ## ### popup() ## disabled -- had issues iwth automatic builds ## msg <- gettext("gWidgets requires a toolkit implementation to be\n installed, for instance gWidgetsRGtk2 or gWidgetstcltk.") ## warning(paste("\n\n**",msg,"**\n\n", sep="")) ## # } } .onAttach <- function(...) { } gWidgets/R/gfile.R0000644000176000001440000000602411511510656013474 0ustar ripleyusers##' @include guiComponents.R ##' dialog for file and directory selection ##' ##' @exports ##' @param text initial text ##' @param type type of browser: to open a file, to save a file or to select a directory ##' @param initialfilename Suggested file name ##' @param filter A filter specifiation. This is toolkit specific ##' @param multi Logical. Allow multiple files to be selected? ##' @param handler called when a file or files have been selected ##' @param action passed to handler ##' @param ... ignored ##' @param toolkit toolkit ##' @return returns filename(s) or \code{NA} if no selection. ##' gfile <- function( text = "", type = c("open", "save", "selectdir"), initialfilename = NULL, filter = list("All files" = list(patterns = c("*")), "R files" = list(patterns = c("*.R", "*.Rdata")), "text files" = list(mime.types = c("text/plain")) ), multi=FALSE, handler = NULL, action = NULL, ... , toolkit=guiToolkit()){ widget = .gfile (toolkit, text=text, type=type, initialfilename=initialfilename, filter=filter, multi=multi, handler=handler, action=action ,... ) } ##' generic for toolkit dispatch ##' ##' @export ##' @rdname gfile setGeneric( '.gfile' , function(toolkit, text = "", type = c("open", "save", "selectdir"), initialfilename = NULL, filter = list("All files" = list(patterns = c("*")), "R files" = list(patterns = c("*.R", "*.Rdata")), "text files" = list(mime.types = c("text/plain")) ), handler = NULL, action = NULL, ... ) standardGeneric( '.gfile' )) ##' class for a widget to select a file setClass("gFilebrowse", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for file/directory selection widget ##' ##' Basically a \code{gedit} instance with a button to initiate \code{gfile}. ##' @export ##' @param text Instructional text ##' @param type type of dialog (see \code{\link{gfile}}) ##' @param quote Do we quote value ##' @param container parent container ##' @param ... passed to \code{add} method of parent ##' @param toolkit toolkit ##' @return Returns an object of class \code{gFilebrowse}. This should ##' inherit the methods of \code{gedit} instances. gfilebrowse <- function ( text = "Select a file...", type = "open", quote = TRUE, container = NULL, ..., toolkit = guiToolkit()) { widget <- .gfilebrowse (toolkit, text=text, type=type, quote=quote, container=container, ...) obj <- new('gFilebrowse',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gfilebrowse setGeneric(".gfilebrowse", function(toolkit, text = "Select a file...", type = "open", quote = TRUE, container = NULL, ...) standardGeneric( '.gfilebrowse' )) gWidgets/R/handlers.R0000644000176000001440000006160711605646157014230 0ustar ripleyusers##' @imports guiComponents ##' ############### removeHandler ################################### ##' generic to remove a handler ##' @alias removeHandler setGeneric("removehandler",function(obj, ID=NULL, ...) standardGeneric("removehandler")) ##' base method to remove a handler ##' @alias removeHandler setMethod("removehandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .removehandler(obj@widget, obj@toolkit, ID, ...) }) ##' dispatch to toolkit ##' @alias removeHandler setGeneric(".removehandler",function(obj, toolkit, ID=NULL, ...) standardGeneric(".removehandler")) ##' generic to define method to remove a handler by ID setGeneric("removeHandler",function(obj, ID=NULL, ...) standardGeneric("removeHandler")) ##' base method to remove a handler ##' ##' @param obj object with event handler set for it ##' @param ID ID of handler returned when handler is set. If NULL, all handlers are removed ##' @return NULL, called for side effect ##' @export setMethod("removeHandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .removehandler(obj@widget, obj@toolkit, ID, ...) }) ############### blockHandler ################################### ##' Generic to block a handler from being called until block is unblocked ##' @alias blockHandler setGeneric("blockhandler",function(obj, ID=NULL, ...) standardGeneric("blockhandler")) ##' base method for blocking a handler by ID ##' @alias blockHandler setMethod("blockhandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .blockhandler(obj@widget, obj@toolkit, ID, ...) }) ##' method for toolkit dispatch ##' @alias blockHandler setGeneric(".blockhandler",function(obj, toolkit, ID=NULL, ...) standardGeneric(".blockhandler")) ##' Generic to define method to block a handler from being called ##' ##' @param obj object with event handler set for it ##' @param ID ID of handler returned when handler is set. If NULL, all handlers are blocked ##' @return NULL, called for side effect ##' @export setGeneric("blockHandler",function(obj, ID=NULL, ...) standardGeneric("blockHandler")) ##' base method to block a handler from being called. setMethod("blockHandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .blockhandler(obj@widget, obj@toolkit, ID, ...) }) ################################################## ##' Generic to define method to unblock a blocked handler setGeneric("unblockhandler",function(obj, ID=NULL, ...) standardGeneric("unblockhandler")) ##' base method to unblock a blocked handler setMethod("unblockhandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .unblockhandler(obj@widget, obj@toolkit, ID, ...) }) ##' method for toolkit dispatch ##' @alias unblockHandler setGeneric(".unblockhandler",function(obj, toolkit, ID=NULL, ...) standardGeneric(".unblockhandler")) ##' Generic for unblocking a blocked handler ##' ##' @param obj object with event handler ##' @param ID id of handler set through addHandlerXXX call ##' @param ... ignored ##' @return NULL, called for side effect ##' @export setGeneric("unblockHandler",function(obj, ID=NULL, ...) standardGeneric("unblockHandler")) setMethod("unblockHandler", signature("guiWidget"), function(obj, ID=NULL, ...) { .unblockhandler(obj@widget, obj@toolkit, ID, ...) }) ################################################## ## addhandler is now exported setGeneric("addhandler",function(obj, signal, handler, action=NULL, ...) standardGeneric("addhandler")) setMethod("addhandler",signature(obj="guiWidget"), function(obj, signal, handler, action=NULL, ...) { toolkit = obj@toolkit .addhandler(obj@widget, toolkit, handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandler",function(obj, toolkit, signal, handler, action=NULL,...) standardGeneric(".addhandler")) ##' Add a handler using toolkit-specific signal ##' ##' This is not portable across toolkits, as the signal passed in a toolkit specific. ##' @param obj gWidgets object to get event handler ##' @param signal toolkit signal defining event ##' @param handler function to call when event occurs. Uses standard signature (h,...) ##' @param action used to parameterize handler call, passed in as \code{h$action} ##' @param ... ignored ##' @return an ID of the handler for blocking or removal ##' @export setGeneric("addHandler",function(obj, signal, handler, action=NULL, ...) standardGeneric("addHandler")) ## setMethod("addHandler",signature(obj="guiWidget"), function(obj, signal, handler, action=NULL, ...) { toolkit = obj@toolkit .addhandler(obj@widget, toolkit, signal, handler, action, ...) }) ## addhandlerchanged setGeneric("addhandlerchanged",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerchanged")) setMethod("addhandlerchanged",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerchanged(obj@widget, toolkit, handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerchanged",function(obj, toolkit,...) standardGeneric(".addhandlerchanged")) ##' Set handler for most typical event ##' ##' The "Changed" handler is set to be called for the most typical ##' event (arbitrarily defined of course). This event varies from ##' widget to widget. It is the same event that the widget ##' constructor's \code{handler} argument is called for. setGeneric("addHandlerChanged",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerChanged")) setMethod("addHandlerChanged",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerchanged(obj@widget, toolkit, handler, action, ...) }) ## addhandlerkeystroke setGeneric("addhandlerkeystroke",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerkeystroke")) setMethod("addhandlerkeystroke",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerkeystroke(obj@widget, toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerkeystroke",function(obj, toolkit,...) standardGeneric(".addhandlerkeystroke")) #caps setGeneric("addHandlerKeystroke",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerKeystroke")) setMethod("addHandlerKeystroke",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerkeystroke(obj@widget, toolkit,handler, action, ...) }) ## addhandlerclicked setGeneric("addhandlerclicked",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerclicked")) setMethod("addhandlerclicked",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerclicked(obj@widget, toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerclicked",function(obj, toolkit,...) standardGeneric(".addhandlerclicked")) ## caps setGeneric("addHandlerClicked",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerClicked")) setMethod("addHandlerClicked",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerclicked(obj@widget, toolkit,handler, action, ...) }) ## addhandlerdoubleclick setGeneric("addhandlerdoubleclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerdoubleclick")) setMethod("addhandlerdoubleclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerdoubleclick(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerdoubleclick",function(obj, toolkit,...) standardGeneric(".addhandlerdoubleclick")) ## caps setGeneric("addHandlerDoubleclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerDoubleclick")) setMethod("addHandlerDoubleclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerdoubleclick(obj@widget,toolkit,handler, action, ...) }) ## addhandlerrightclick setGeneric("addhandlerrightclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerrightclick")) setMethod("addhandlerrightclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerrightclick(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerrightclick",function(obj,toolkit,...) standardGeneric(".addhandlerrightclick")) ## caps setGeneric("addHandlerRightclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerRightclick")) setMethod("addHandlerRightclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerrightclick(obj@widget,toolkit,handler, action, ...) }) ### ## Column clicks ## clicked setGeneric("addhandlercolumnclicked",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlercolumnclicked")) setMethod("addhandlercolumnclicked",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumnclicked(obj@widget, toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlercolumnclicked",function(obj, toolkit,...) standardGeneric(".addhandlercolumnclicked")) ## caps setGeneric("addHandlerColumnClicked",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerColumnClicked")) setMethod("addHandlerColumnClicked",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumnclicked(obj@widget, toolkit,handler, action, ...) }) ## addhandlerCOLUMNdoubleclick setGeneric("addhandlercolumndoubleclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlercolumndoubleclick")) setMethod("addhandlercolumndoubleclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumndoubleclick(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlercolumndoubleclick",function(obj, toolkit,...) standardGeneric(".addhandlercolumndoubleclick")) ## caps setGeneric("addHandlerColumnDoubleclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerColumnDoubleclick")) setMethod("addHandlerColumnDoubleclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumndoubleclick(obj@widget,toolkit,handler, action, ...) }) ## columnrightclick ## addhandlerCOLUMNdoubleclick setGeneric("addhandlercolumnrightclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlercolumnrightclick")) setMethod("addhandlercolumnrightclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumnrightclick(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlercolumnrightclick",function(obj, toolkit,...) standardGeneric(".addhandlercolumnrightclick")) ## caps setGeneric("addHandlerColumnRightclick",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerColumnRightclick")) setMethod("addHandlerColumnRightclick",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlercolumnrightclick(obj@widget,toolkit,handler, action, ...) }) ## Selections setGeneric("addhandlerselect",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerselect")) setMethod("addhandlerselect",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerselect(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerselect",function(obj,toolkit,...) standardGeneric(".addhandlerselect")) ## caps setGeneric("addHandlerSelect",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerSelect")) setMethod("addHandlerSelect",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerselect(obj@widget, toolkit, handler, action, ...) }) ## addhandlerFocus setGeneric("addhandlerfocus",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerfocus")) setMethod("addhandlerfocus",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerfocus(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerfocus",function(obj,toolkit,...) standardGeneric(".addhandlerfocus")) ## caps setGeneric("addHandlerFocus",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerFocus")) setMethod("addHandlerFocus",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerfocus(obj@widget,toolkit,handler, action, ...) }) ## addhandlerblur setGeneric("addhandlerblur",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerblur")) setMethod("addhandlerblur",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerblur(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerblur",function(obj,toolkit,...) standardGeneric(".addhandlerblur")) ## caps setGeneric("addHandlerBlur",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerBlur")) setMethod("addHandlerBlur",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerblur(obj@widget,toolkit,handler, action, ...) }) ## addhandlerdestroy setGeneric("addhandlerdestroy",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerdestroy")) setMethod("addhandlerdestroy",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerdestroy(obj@widget, toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerdestroy",function(obj,toolkit,...) standardGeneric(".addhandlerdestroy")) ##caps setGeneric("addHandlerDestroy",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerDestroy")) setMethod("addHandlerDestroy",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerdestroy(obj@widget, toolkit,handler, action, ...) }) # addhandlerexpose setGeneric("addhandlerexpose",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerexpose")) setMethod("addhandlerexpose",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerexpose(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerexpose",function(obj, toolkit,...) standardGeneric(".addhandlerexpose")) ## caps setGeneric("addHandlerExpose",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerExpose")) setMethod("addHandlerExpose",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerexpose(obj@widget,toolkit,handler, action, ...) }) # addhandlerunrealize ##' handler when window is unrealized ##' ##' For gwindow objects this handler is called before the window is closed. If this handler ##' returns \code{TRUE} the window will be close, if \code{FALSE} the window will not be closed. ##' @param obj gWidget object ##' @param handler function with signature (h,...) to call when event occurs ##' @param action value passed to handler function in component \code{h$action} ##' @param ... ignored ##' @return ID of handler, used for blocking or removing ##' @export ##' @examples ##' \dontrun{ ##' w <- gwindow("Really close?") ##' addHandlerUnrealize(w, handler=function(h,...) { ##' gconfirm("Really close?", parent=w) ##' }) ##' } setGeneric("addhandlerunrealize",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlerunrealize")) setMethod("addhandlerunrealize",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerunrealize(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlerunrealize",function(obj, toolkit,...) standardGeneric(".addhandlerunrealize")) ## caps setGeneric("addHandlerUnrealize",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerUnrealize")) setMethod("addHandlerUnrealize",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlerunrealize(obj@widget,toolkit,handler, action, ...) }) ## mousemotion ##' Handler to respond to mouse motion ##' ##' Movement of mouse over widget triggers this handler ##' @param obj gWidget object ##' @param handler function with signature (h,...) to call when event occurs ##' @param action value passed to handler function in component \code{h$action} ##' @param ... ignored ##' @return ID of handler, used for blocking or removing ##' @export setGeneric("addhandlermousemotion",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addhandlermousemotion")) setMethod("addhandlermousemotion",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlermousemotion(obj@widget,toolkit,handler, action, ...) }) ## dispatch with toolkit setGeneric(".addhandlermousemotion",function(obj, toolkit,...) standardGeneric(".addhandlermousemotion")) ## caps setGeneric("addHandlerMouseMotion",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addHandlerMouseMotion")) setMethod("addHandlerMouseMotion",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .addhandlermousemotion(obj@widget,toolkit,handler, action, ...) }) # addhandleridle setGeneric("addhandleridle",function(obj, handler=NULL, action=NULL, interval=1000, ...) standardGeneric("addhandleridle")) setMethod("addhandleridle",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, interval=1000, ...) { toolkit = obj@toolkit .addhandleridle(obj@widget, toolkit, handler=handler, action=action, interval=interval, ...) }) ## dispatch with toolkit setGeneric(".addhandleridle",function(obj, toolkit,handler=NULL,action=NULL, interval=1000,...) standardGeneric(".addhandleridle")) ## caps setGeneric("addHandlerIdle",function(obj, handler=NULL, action=NULL, interval=1000, ...) standardGeneric("addHandlerIdle")) setMethod("addHandlerIdle",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, interval=1000, ...) { toolkit = obj@toolkit .addhandleridle(obj@widget, toolkit, handler=handler, action=action, interval=interval, ...) }) ## addpopupmenu setGeneric("addpopupmenu",function(obj, menulist, action=NULL, ...) standardGeneric("addpopupmenu")) setMethod("addpopupmenu",signature(obj="guiWidget"), function(obj, menulist, action=NULL, ...) { toolkit = obj@toolkit .addpopupmenu(obj@widget, toolkit,menulist, action, ...) }) ## dispatch with toolkit setGeneric(".addpopupmenu",function(obj, toolkit, menulist, action=NULL, ...) standardGeneric(".addpopupmenu")) ## caps setGeneric("addPopupmenu",function(obj, menulist, action=NULL, ...) standardGeneric("addPopupmenu")) setMethod("addPopupmenu",signature(obj="guiWidget"), function(obj, menulist, action=NULL, ...) { toolkit = obj@toolkit .addpopupmenu(obj@widget, toolkit,menulist, action, ...) }) ## add3rdmousepopupmenu setGeneric("add3rdmousepopupmenu",function(obj, menulist, action=NULL, ...) standardGeneric("add3rdmousepopupmenu")) setMethod("add3rdmousepopupmenu",signature(obj="guiWidget"), function(obj, menulist, action=NULL, ...) { .add3rdmousepopupmenu(obj@widget, obj@toolkit, menulist, action=action, ...) }) ## dispatch with toolkit setGeneric(".add3rdmousepopupmenu",function(obj, toolkit,menulist, action=NULL, ...) standardGeneric(".add3rdmousepopupmenu")) ## caps setGeneric("add3rdMousePopupmenu",function(obj, menulist, action=NULL, ...) standardGeneric("add3rdMousePopupmenu")) setMethod("add3rdMousePopupmenu",signature(obj="guiWidget"), function(obj, menulist, action=NULL, ...) { .add3rdmousepopupmenu(obj@widget, obj@toolkit, menulist, action=action, ...) }) ## adddropsource setGeneric("adddropsource",function(obj, targetType="text", handler=NULL, action=NULL, ...) standardGeneric("adddropsource")) setMethod("adddropsource",signature(obj="guiWidget"), function(obj, targetType="text", handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddropsource(obj@widget, toolkit,targetType=targetType, handler=handler, action=action, ...) }) ## dispatch with toolkit setGeneric(".adddropsource",function(obj, toolkit,targetType="text", handler=NULL, action=NULL, ...) standardGeneric(".adddropsource")) ## caps setGeneric("addDropSource",function(obj, targetType="text", handler=NULL, action=NULL, ...) standardGeneric("addDropSource")) setMethod("addDropSource",signature(obj="guiWidget"), function(obj, targetType="text", handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddropsource(obj@widget, toolkit,targetType=targetType, handler=handler, action=action, ...) }) ## adddropmotion setGeneric("adddropmotion",function(obj, handler=NULL, action=NULL, ...) standardGeneric("adddropmotion")) setMethod("adddropmotion",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddropmotion(obj@widget, toolkit, handler=handler, action=action, ...) }) ## dispatch with toolkit setGeneric(".adddropmotion",function(obj, toolkit, handler=NULL, action=NULL, ...) standardGeneric(".adddropmotion")) ## caps setGeneric("addDropMotion",function(obj, handler=NULL, action=NULL, ...) standardGeneric("addDropMotion")) setMethod("addDropMotion",signature(obj="guiWidget"), function(obj, handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddropmotion(obj@widget, toolkit, handler=handler, action=action, ...) }) ## adddroptarget setGeneric("adddroptarget",function(obj, targetType="text", handler=NULL, action=NULL, ...) standardGeneric("adddroptarget")) setMethod("adddroptarget",signature(obj="guiWidget"), function(obj, targetType="text", handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddroptarget(obj@widget, toolkit,targetType=targetType, handler=handler, action=action, ...) }) ## dispatch with toolkit setGeneric(".adddroptarget",function(obj, toolkit,targetType="text", handler=NULL, action=NULL, ...) standardGeneric(".adddroptarget")) ## caps setGeneric("addDropTarget",function(obj, targetType="text", handler=NULL, action=NULL, ...) standardGeneric("addDropTarget")) setMethod("addDropTarget",signature(obj="guiWidget"), function(obj, targetType="text", handler=NULL, action=NULL, ...) { toolkit = obj@toolkit .adddroptarget(obj@widget, toolkit,targetType=targetType, handler=handler, action=action, ...) }) gWidgets/R/gtable.R0000644000176000001440000000716011621475230013646 0ustar ripleyusers##' @include guiComponents.R ##' Class for tabular data display: gdf, gtable setClass("gGridComponent", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' svalue method for gdf or gtable widget ##' ##' Main property of a table is the selection ##' @param obj object ##' @param index if \code{index=NULL} or \code{FALSE} then values from ##' the table are given if \code{index=TRUE} then the indices are ##' returned. The value of \code{drop} deteremines what is returned. ##' @param drop if \code{NULL} or \code{TRUE} then when ##' \code{index=TRUE} the indices of the currently selected rows are ##' returned. If \code{index=FALSE} then the values from the chosen ##' column are returned. Otherwise, if \code{drop=FALSE} then when ##' \code{index=TRUE} then -- if the toolkit supports it -- a list with ##' components \code{rows} and \code{columns} describing rectangles ##' of selected values. ##' @return a vector or data frame of values, or a vector or list of ##' indices. If no selection returns \code{NULL}. setMethod("svalue", signature(obj="gGridComponent"), function(obj, index=NULL, drop=NULL, ... ) { .svalue(obj@widget, obj@toolkit, ...,index=index, drop=drop) }) ##' set selection in gdf or gtable object ##' ##' @param obj ##' @param index if \code{NULL} or \code{FALSE} then a specification ##' by match on the chosen columns. If \code{TRUE} then a ##' specification of indices. This can be as a vector of row indices, ##' or as a list with row and column specifications. ##' @param value replacement value setReplaceMethod("svalue", signature(obj="gGridComponent"), function(obj, index=NULL, ...,value) { .svalue(obj@widget, obj@toolkit, index=index, ...) <- value return(obj) }) ## leftbracket -- column coercion an issue, resizing frames an issue, replacement method ## leftbracket<- ## dim, dimnames, length, names, .... ################################################## ##' class to display tabular data for selection setClass("gTable", contains="gGridComponent", prototype=prototype(new("gGridComponent")) ) ##' A constructor for displaying tabular data for selection ##' ##' @exports gtable <- function( items, multiple = FALSE, chosencol = 1, icon.FUN = NULL, filter.column = NULL, filter.labels = NULL, filter.FUN = NULL, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ ## coerce items if(!missing(items)) { if (is.vector(items)) items <- data.frame(Values=items, stringsAsFactors=FALSE) if(is.matrix(items)) items <- data.frame(items, stringsAsFactors=FALSE) } widget <- .gtable (toolkit, items=items, multiple=multiple, chosencol=chosencol, icon.FUN=icon.FUN, filter.column=filter.column, filter.labels=filter.labels, filter.FUN=filter.FUN, handler=handler, action=action, container=container ,... ) obj <- new( 'gTable',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gtable setGeneric( '.gtable' , function(toolkit, items, multiple = FALSE, chosencol = 1, icon.FUN = NULL, filter.column = NULL, filter.labels = NULL, filter.FUN = NULL, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gtable' )) ## handler code in subclasses ## addHandlerChanged, addHandlerClicked gWidgets/R/common.R0000644000176000001440000001415611604711442013702 0ustar ripleyusers## Some functions that seem to be useful. These are not exported, ## hence repeated in gWidgetsR****. This should likely be changed, but ## for now it isn't gwCat <- function(...) { doCat <- getOption("gWidgetsDebug") if(!is.null(doCat)) message(...) } Paste = function(..., sep="", collapse="") { x = unlist(list(...)) x = x[!is.na(x)] x = x[x != "NA"] paste(x, sep=sep, collapse=collapse) } PasteWithComma = function(...) { args = unlist(list(...)) args = args[!is.na(args)] paste(args, sep="", collapse=", ") } quoteIfNeeded = function(str) { if(length(grep('^\\".*\\"$', str, perl=TRUE)) > 0 || length(grep("^\\'.*\\'$", str, perl=TRUE)) > 0 ) return(str) else return(paste('"',str,'"',sep="",collapse="")) } ## ReadParseEvaL -- saves typing rpel = function(string, envir=.GlobalEnv) { eval(parse(text=string), envir=envir) } ## return type str1 <- function(obj) { md <- mode(obj) lg <- length(obj) objdim <- dim(obj) if (length(objdim) == 0) dim.field <- paste("length:", lg) else { dim.field <- "dim:" for (i in 1:length(objdim)) dim.field <- paste(dim.field, objdim[i]) if (is.matrix(obj)) md <- "matrix" } obj.class <- oldClass(obj) if (!is.null(obj.class)) { md <- obj.class[1] if (inherits(obj, "factor")) dim.field <- paste("levels:", length(levels(obj))) } list( type = md, dim.field = dim.field) } ## untaint a variable name so that $ can be used untaintName = function(objName) { if (length(grep(" |\\+|\\-|\\*|\\/\\(|\\[|\\:",objName)) > 0) { objName=Paste("\"",objName,"\"") } return(objName) } ## as name says stripWhiteSpace = function(str) { sub('[[:space:]]+$', '', str) ## from ?gsub sub('^[[:space:]]+', '', str) ## from ?gsub return(str) } ### We should make this configurable. Likely using options ### Use this for filtering .datasets = c( "numeric","logical","factor","character", "data.frame","matrix","list", "table","xtabs", "nfnGroupedData","nffGroupedData","nmGroupedData" ) .models = c("lm","glm","lqs","aov","anova", "lme","lmList","gls", "ar","arma","arima0","fGARCH","fAPARCH" ) .ts = c("ts", "mts", "timeSeries", "its", "zoo") .functions=c("function") .plots = c("recordedplot") knownTypes = list( "data sets and models"=c(.datasets, .models, .ts), "data sets"= c(.datasets,.ts), "model objects" = .models, "time series objects" = .ts, "functions"=.functions, "saved plots" = .plots, "all" = NULL ) ## get does not work with name$component, this gets around that ## returns NULL if not available getObjectFromString = function(STRING="", envir=.GlobalEnv) { tmp = try(get(STRING, envir), silent = TRUE) if(!inherits(tmp, "try-error")) return(tmp) tmp = try(rpel(STRING,envir), silent=TRUE) if(!inherits(tmp, "try-error")) return(tmp) ## out of chances return(NULL) } ## Find the name of the object by pasting toghther the pieces ## better to do name$name, but value may be a numeric makeObjectName = function(root,value) { if(is.null(root)) return(untaintName(value)) ## now decide between $ and [[]] if(value == make.names(value)) { return(Paste(root,"$",untaintName(value))) } else { return(Paste(root,"[['",value,"']]")) } } ## a function to get objects and their types ## filter is a vector of classes getObjectsWithType = function(root=NULL, filter = NULL, envir=.GlobalEnv) { if(is.null(root)) { objects = ls(envir=envir) } else { string = Paste("with(",root,",ls())") objects = try(rpel(string,envir=envir), silent=TRUE) } ## objects is character vector of components of root. badnames = grep("[[<-]|\\*",objects) if(length(badnames) > 0) objects = objects[-badnames] objectsWithRoot = sapply(objects,function(i) makeObjectName(root,i)) type = sapply(objectsWithRoot, function(i) { string = Paste("str2(",i,")") rpel(string, envir=envir) }) objects = data.frame(Name=objects,Type=type,stringsAsFactors=FALSE) ## filter if(!is.null(filter)) objects = objects[type %in% filter,] return(objects) } ## get the names of the object, if available (datastores) getNamesofObject = function(string="") { ## if empty string, get variables in .GlobalEnv if(string == "") { ## return objects of certain type objects = getObjectsWithType(root=NULL, filter=knownTypes[['data sets']]) return(unlist(objects$Name)) } obj = getObjectFromString(string) if(!is.null(obj)) { if(is.list(obj)) { return(names(obj)) } else if(is.matrix(obj)) { return(colnames(obj)) } else{ return(NULL) } } else { return(NULL) } } ## used to check output is.empty = function(obj) { if(is.null(obj) || is.na(obj) || (is.character(obj) && obj == "")) { return(TRUE) } else { return(FALSE) } } ## fix font mess up DEPRECATED!! .fixFontMessUp = function(val) { if(is.vector(val)) { tmp = val val = list() for(i in names(tmp)) val[[i]] = tmp[i] } weights = c("normal","oblique", "italic") styles = c("ultra-light","light","normal","bold","ultra-bold", "heavy") a = val$weight; b = val$style if((!is.null(a) && a %in% styles) || (!is.null(b) &&b %in% weights)) { tmp = a val$weight <- b val$style <- a } return(val) } ## what type of object is thixs and a size str2 <- function(obj) { md <- mode(obj) if (is.matrix(obj)) md <- "matrix" obj.class <- oldClass(obj) if (!is.null(obj.class)) { md <- obj.class[1] } return(md) } ## blurb about installation -- put in so can be updated easily ## look to file to update installing_gWidgets_toolkits <- function() { file <- system.file("install/Installing_gWidgets_Toolkits.txt", package="gWidgets") tmp <- readLines(file) for(i in tmp) cat(i,"\n") } ##' return x unless null then give default getWithDefault <- function(x, default) ifelse(is.null(x) || is.na(x) || x == "", default, x) ## ID is used by the ANY widgets n=0;assignInNamespace("n",0,"gWidgets") getNewID = function() { # get new one, incremented n = getFromNamespace("n",ns="gWidgets") assignInNamespace("n",n+1,ns="gWidgets") return(n+1) } gWidgets/R/gradio.R0000644000176000001440000000240511626201566013656 0ustar ripleyusers##' @include guiComponentWithItems.R ##' Radio button class setClass("gRadio", contains="guiComponentWithItems", prototype=prototype(new("guiComponentWithItems")) ) ##' Constructor for radio button widget gradio = function(items,selected=1, horizontal=FALSE, handler=NULL, action=NULL, container=NULL, ..., toolkit=guiToolkit()) { ## check input if(length(x <- unique(items) ) != length(items)) gwCat("Using unique items for selection values") radio = .gradio(toolkit, x, selected, horizontal, handler, action, container,...) obj = new("gRadio",widget=radio, toolkit=toolkit) return(obj) } ##' method for dispatch into toolkit setGeneric(".gradio",function(toolkit, items, selected=1, horizontal=FALSE, handler=NULL, action=NULL, container=NULL, ...) standardGeneric(".gradio")) ##' replace selections ##' ##' Ensure values are unique setReplaceMethod("[",signature(x="gRadio"), function(x, i, j,...,value) { ## check input if(length(value) != length(value <- unique(value))) gwCat("Using unique values for selection values") callNextMethod(x, i, j, ..., value=value) }) gWidgets/R/gcombobox.R0000644000176000001440000001041511626172670014373 0ustar ripleyusers##' @include guiComponentWithItems.R ##' Combobox class setClass("gCombobox", contains="guiComponentWithItems", prototype=prototype(new("guiComponentWithItems")) ) ##' constructor for combobox ##' ##' @export ##' @param items Items to select from. A vector or a data frame. If a ##' data frame, then first column is values. Second is optional, but ##' can specify a stock icon name, third is optional and can be used ##' to specify a tooltip. These may not be supported in all toolkits. ##' @param selected integer. Which item (by index) is selected. Use -1 for no selection ##' @param editable logical. Is user allowed to edit value ##' @param coerce.with A function of function name to be called before ##' selected value is returned by \code{svalue} ##' @param handler Called when combobox value is changed. ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to parent container's \code{add} method ##' @param toolkit toolkit ##' @return Returns an object of class \code{gCombobox} for which the following methods are overriden: ##' \enumerate{ ##' \item \code{svalue} Return selected value by name or (if \code{index=TRUE} by index). The latter only if \code{editable=FALSE}. ##' ##' \item \code{\svalue<-} Set the selected value by value or if \code{index=TRUE} by index. ##' ##' \item \code{[} return items to select from ##' ##' \item \code{[<-} Set items to select from. ##' } ##' @example ~/pmg/r-forge/gwidgets/pkg/gWidgets/inst/tests/ex-gcombobox.R gcombobox =function( items, selected = 1, editable = FALSE, coerce.with=NULL, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ ## adjust items. Pass in data frame if(!is.data.frame(items) && !is.matrix(items)) items <- data.frame(items, stringsAsFactors=FALSE) if(!is.data.frame(items)) items <- as.data.frame(items) widget = .gdroplist (toolkit, items=items, selected=selected, editable=editable, coerce.with=coerce.with, handler=handler, action=action, container=container, ... ) obj = new( 'gCombobox',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' ##' @alias gcombobox setGeneric( '.gdroplist' , function(toolkit, items, selected = 1, editable = FALSE, coerce.with = NULL, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gdroplist' )) ##' Alias for gcombobox. Deprecated ##' ##' @alias gcombobox gdroplist <- gcombobox ##' svalue method for combobox ##' ##' Main property of checkbox group are the states. ##' @param obj object ##' @param index If \code{TRUE} returns index of selected. Otherwise a character vector. ##' @param drop ignored ##' @return character or index. Some toolkits return \code{-1} when nothing is selected. ##' @exports setMethod("svalue", signature(obj="gCombobox"), function(obj, index=NULL, drop=NULL, ... ) { .svalue(obj@widget, obj@toolkit, ...,index=index, drop=drop) }) ##' set state for combobox ##' ##' @param obj ##' @param index if \code{TRUE} then an index is expected. If \code{FALSE}, then name should match available unless \code{editable=TRUE} is specified ##' @param ... ignored ##' @param value numeric or character depending on \code{index} ##' @return void ##' @exports setReplaceMethod("svalue", signature(obj="gCombobox"), function(obj, index=NULL, ...,value) { .svalue(obj@widget, obj@toolkit, index=index, ...) <- value return(obj) }) ##' replacement method for combobox selection items ##' ##' Ensure that value is a data frame. One can pass a vector or a ##' one-column data frame to inidicate the possible values for ##' selection, a second column is used for an icons (if possible), a ##' third for a tooltip (if possible). ##' get_from_templace for guiWidget setReplaceMethod("[",signature(x="gCombobox"), function(x,i,j,...,value) { ## adjust value. Pass in data frame if(!is.data.frame(value) && !is.matrix(value)) value <- data.frame(value, stringsAsFactors=FALSE) if(!is.data.frame(value)) value <- as.data.frame(value) callNextMethod(x, i, j, ..., value=value) }) gWidgets/R/bbbGenericsANY.R0000644000176000001440000002126212313662423015165 0ustar ripleyusersrequire(methods) require(utils) ## Set up generics and classes for ANY widgets. ## ANY widgets are meant to work with any toolkit. They are compound widgets ## their methods are not inherited from the toolkit ones, but rather are made explicit here. ## how to make a generic widget here? ### Methods ## We need these methods to get the dispatch correct. ## TAG method uses ID ## This is taken from gWIdgets tcltk. It uses a big hash. Ughh ## create namespace object tags = list() assignInNamespace("tags",list(),"gWidgets") ## clear out tags for this ID. Not exported. Is this used? Tagsclear = function(obj) { id = obj@ID tags = getFromNamespace("tags",ns="gWidgets") allKeys = names(tags) inds = grep(paste("^",id,"::",sep=""),allKeys) if(length(inds) == 0) return(NA) ## else tags[[inds]] <- NULL assignInNamespace("tags",tags,ns="gWidgets") } setMethod("tag",signature(obj="gWidgetANY"), function(obj,i,drop=TRUE, ...) { if(missing(drop)) drop <- TRUE .tag(obj, obj@toolkit,i, drop=drop,...) }) setMethod(".tag", signature(toolkit="ANY",obj="guiWidget"), function(obj, toolkit, i, drop=TRUE, ...) { if(missing(i)) i = NULL if(missing(drop)) drop <- TRUE .tag(obj@widget,toolkit, i, drop=drop, ...) }) setMethod(".tag", signature(toolkit="ANY",obj="gWidgetANY"), function(obj, toolkit, i, drop=TRUE, ...) { if(missing(i)) i = NULL if(missing(drop)) drop <- TRUE id = obj@ID ## get all values for this id tags = getFromNamespace("tags",ns="gWidgets") allKeys = names(tags) inds = grep(paste("^",id,"::",sep=""),allKeys) if(length(inds) == 0) return(NULL) justTheKeys = sapply(allKeys[inds],function(keyWithID) { sub(paste("^",id,"::",sep=""),"",keyWithID) }) tagByKey = list() for(key in justTheKeys) tagByKey[[key]] = tags[[paste(id,key,sep="::")]] if(is.null(i)) return(tagByKey) if(drop) { if(length(i) == 1) return(tagByKey[[i]]) else return(sapply(i, function(j) tagByKey[j])) } else { return(sapply(i, function(j) tagByKey[j])) } }) ## tag <- setReplaceMethod("tag",signature(obj="gWidgetANY"), function(obj, i, replace=TRUE, ..., value) { .tag(obj, obj@toolkit,i,replace, ...) <- value return(obj) }) ## objects can be in many different flavors: guiWIdget, gWidgettcltk, tcltkObject setReplaceMethod(".tag", signature(toolkit="ANY",obj="guiWidget"), function(obj, toolkit, i, replace=TRUE, ..., value) { if(missing(i)) i = NULL .tag(obj@widget,toolkit, i, replace, ...) <- value return(obj) }) setReplaceMethod(".tag", signature(toolkit="ANY",obj="gWidgetANY"), function(obj, toolkit, i, replace=TRUE, ..., value) { if(missing(i)) i = NULL id = obj@ID key = paste(id,i,sep="::") ## if we append we need to work a little harder tags = getFromNamespace("tags",ns="gWidgets") if(replace==FALSE) { value = c(tags[[key]],value) } tags[[key]] <- value assignInNamespace("tags", tags,ns="gWidgets") return(obj) }) ### svalue ## Generic svalue setMethod(".svalue",signature(toolkit = "ANY", obj="character"), function(obj, toolkit, index=NULL, drop=NULL, ...) { ifelse(length(obj) == 1, return(getObjectFromString(obj)), return(NA) ) }) setMethod(".svalue",signature(toolkit = "ANY", obj="NULL"), function(obj, toolkit, index=NULL, drop=NULL, ...) { return(NULL) }) setMethod("svalue",signature(obj="gWidgetANY"), function(obj, index=NULL, drop=NULL, ... ) { toolkit = obj@toolkit .svalue(obj, toolkit, ...,index=index, drop=drop) }) ## svalue<- -- objec specific setReplaceMethod("svalue",signature(obj="gWidgetANY"), function(obj, index=NULL, ...,value) { .svalue(obj, obj@toolkit, index=index, ...) <- value return(obj) }) ## [. [<- ## [ setMethod("[", signature(x="gWidgetANY"), function(x,i,j,...,drop=TRUE) { return(.leftBracket(x, x@toolkit,i,j,...,drop=TRUE)) }) ## [<- setReplaceMethod("[",signature(x="gWidgetANY"), function(x,i,j,...,value) { if(missing(i) && missing(j)) .leftBracket(x, x@toolkit,...) <- value else if(missing(j)) .leftBracket(x, x@toolkit,i,...) <- value else .leftBracket(x, x@toolkit,i,j,...) <- value return(x) }) ## size<- setReplaceMethod("size",signature(obj="gWidgetANY"), function(obj, ..., value) { .size(obj, obj@toolkit,...) <- value return(obj) }) ## visible setMethod("visible",signature(obj="gWidgetANY"), function(obj, set=NULL, ...) { .visible(obj,obj@toolkit, set=set, ...) }) setReplaceMethod("visible",signature(obj="gWidgetANY"), function(obj, ..., value) { .visible(obj, obj@toolkit, ...) <- value return(obj) }) ## enabled -- TRUE If state is normal setMethod("enabled",signature(obj="gWidgetANY"), function(obj, ...) { .enabled(obj, obj@toolkit,...) }) setReplaceMethod("enabled",signature(obj="gWidgetANY"), function(obj, ..., value) { .enabled(obj, obj@toolkit,...) <- value return(obj) }) setMethod("focus",signature(obj="gWidgetANY"), function(obj, ...) { .focus(obj, obj@toolkit,...) }) setReplaceMethod("focus",signature(obj="gWidgetANY"), function(obj, ..., value) { .focus(obj, obj@toolkit,...) <- value return(obj) }) ## font<- setReplaceMethod("font",signature(obj="gWidgetANY"), function(obj, ..., value) { .font(obj, obj@toolkit,...) <- value return(obj) }) ## update setMethod("update",signature(object="gWidgetANY"), function(object, ...) { .update(object, object@toolkit, ...) }) ## dimnames setMethod("dimnames", "gWidgetANY", function(x) .dimnames(x,x@toolkit)) setReplaceMethod("dimnames", signature(x="gWidgetANY"), function(x,value) { .dimnames(x,x@toolkit) <- value return(x) }) ## as of 2.5.0 this became primiive if(as.numeric(R.Version()$major) <= 2 & as.numeric(R.Version()$minor) <= 4.1) { setGeneric("names") setGeneric("names<-") } setMethod("names", "gWidgetANY", function(x) .names(x,x@toolkit)) setReplaceMethod("names", signature(x="gWidgetANY"), function(x,value) { .names(x,x@toolkit) <- value return(x) }) ## add for widgets (gtext, ghelp, ...) ## Container methods are in toolkits implementations setMethod("add",signature(obj="ANY"), function(obj, value, ...) { .add(obj, obj@toolkit,value,...) }) setMethod(".add", signature(toolkit="ANY", obj="ANY", value="gWidgetANY"), function(obj, toolkit, value, ...) { .add(obj, toolkit, value@widget, ...) }) ## undo and redo only implemented in some toolkits setMethod("undo",signature(obj="gWidgetANY"), function(obj,...) { .undo(obj, obj@toolkit,...) }) setMethod(".undo", signature(toolkit="ANY",obj="guiWidget"), function(obj, toolkit, ...) { .undo(obj@widget,toolkit,...) }) setMethod(".undo", signature(toolkit="ANY",obj="gWidgetANY"), function(obj,toolkit, ...) { ## nothing }) setMethod("redo",signature(obj="gWidgetANY"), function(obj,...) { .redo(obj, obj@toolkit,...) }) setMethod(".redo", signature(toolkit="ANY",obj="guiWidget"), function(obj, toolkit, ...) { .redo(obj@widget,toolkit) }) setMethod(".redo", signature(toolkit="ANY",obj="gWidgetANY"), function(obj, toolkit, ...) { ## nothing }) gWidgets/R/gcheckbox.R0000644000176000001440000000461211626201405014340 0ustar ripleyusers##' @include guiComponents.R ##' Checkbox class setClass("gCheckbox", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for checkbox widget ##' ##' A checkbox widget has a checkbox or toggle button to indicate selection or not ##' @param text label text ##' @param checked is button selected ##' @param use.togglebutton Use a toggle button (shows depressed) not a check box ##' @param handler Callback called when toggle is changed. ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to \code{add} method of container ##' @param toolkit toolkit ##' @example ~/pmg/r-forge/gwidgets/pkg/gWidgets/inst/tests/ex-gcheckbox.R ##' @export ##' @return Returns an object of class \code{gCheckbox} for which the ##' following methods are overridden: ##' % ##' \enumerate{ ##' \item \code{svalue} gets state by boolean value ##' ##' \item \code{svalue<-} sets state by boolean value ##' ##' \item \code{[} Returns label ##' ##' \item \code{[<-} sets label ##' } gcheckbox =function( text, checked = FALSE, use.togglebutton=FALSE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ ## ensure text is given if(missing(text)) text <- "" text <- as.character(text)[1] ## checked is logical checked <- as.logical(checked)[1] widget = .gcheckbox (toolkit, text=text, checked=checked, use.togglebutton=use.togglebutton, handler=handler, action=action, container=container, ... ) obj = new( 'gCheckbox',widget=widget,toolkit=toolkit) return(obj) } ##' Generic for toolkit dispatch ##' @alias gcheckbox setGeneric( '.gcheckbox' , function(toolkit, text, checked = FALSE, use.togglebutton=FALSE, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gcheckbox' )) ##' svalue method ##' ##' Ensure value is logical setReplaceMethod("svalue",signature(obj="gCheckbox"), function(obj, index=NULL, ...,value) { value <- as.logical(value)[1] callNextMethod(obj, index, ..., value=value) }) ##' ensure value is character of length 1 setReplaceMethod("[",signature(x="gCheckbox"), function(x,i,j,...,value) { value <- as.character(value)[1] callNextMethod(x, i, j, ..., value=value) }) gWidgets/R/gdf.R0000644000176000001440000000364011511507111013137 0ustar ripleyusers##' @include gtable.R ##' Class for a data frame editor setClass("gDf", contains="gGridComponent", prototype=prototype(new("gGridComponent")) ) ##' Constructor for a data frame editor ##' ##' @exports ##' @param items data frame to edit ##' @param name name of data frame (for saving, but not really needed) ##' @param do.subset logical. If \code{TRUE} a combobox to subset values by is produced. ##' @param container parent container ##' @param ... passed to container's \code{add} method ##' @param toolkit toolkit ##' @return An object of class \code{gDf} with overridden methods: ##' ##' \enumerate{ ##' ##' \item \code{svalue} to return the selected cells ##' ##' \item \code{svalue<-} to set the selected cells ##' ##' \item \code{[} to get the current values ##' ##' \item \code{[<-} to set the current values. For most toolkits one ##' can not coerce the underlying class of a column (say from numeric ##' to character) ##' ##' \item \code{dim} dimension of object ##' ##' \item \code{length} number of columns ##' ##' } ##' ##' The widget may have underlying handlers assigned by \code{addHandlerClicked} ##' ##' } ##' gdf <- function( items = NULL, name = deparse(substitute(items)), do.subset = FALSE, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gdf (toolkit, items=items, name=name, do.subset=do.subset, container=container ,... ) obj <- new( 'gDf',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gdf setGeneric( '.gdf' , function(toolkit, items = NULL, name = deparse(substitute(items)), do.subset = FALSE, container = NULL, ... ) standardGeneric( '.gdf' )) ## methods ## addHandlerChanged, addHandlerClicked, addHandlerDoubleClicked ## addHandlerColumnClicked, addHandlerColumnDoubleClicked gWidgets/R/ggraphics.R0000644000176000001440000000360311436253612014357 0ustar ripleyusers##' @include guiComponents.R ##' Class for graphic device widget setClass("gGraphics", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' Constructor for an embeddable graphics device ##' ##' @exports ggraphics <- function( width = dpi * 6, height = dpi * 6, dpi = 75, ps = 12, container = NULL, ... , toolkit=guiToolkit()){ widget <- .ggraphics (toolkit, width=width, height=height, dpi=dpi, ps=ps, container=container ,... ) obj <- new( 'gGraphics',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias ggraphics setGeneric( '.ggraphics' , function(toolkit, width = dpi * 6, height = dpi * 6, dpi = 75, ps = 12, container = NULL, ... ) standardGeneric( '.ggraphics' )) ##' Class for notebook to hold multiple ggraphics widgets setClass("gGraphicsNotebook", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for notebook to hold multiple graphics devices ##' ##' @export ggraphicsnotebook <- function( width = dpi * 6, height = dpi * 6, dpi = 75, container = NULL, ... , toolkit=guiToolkit()){ widget <- .ggraphicsnotebook (toolkit, width=width, height=height, dpi=dpi, container=container ,... ) obj <- new( 'gGraphicsNotebook',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias ggraphicsnotebook setGeneric( '.ggraphicsnotebook' , function(toolkit, width = dpi * 6, height = dpi * 6, dpi = 75, container = NULL, ... ) standardGeneric( '.ggraphicsnotebook' )) gWidgets/R/gvariables.R0000644000176000001440000007147312377440535014550 0ustar ripleyusers## interface to variables used by ggenericwidget ##TODO: ## * responsevar-- droplist (update with data), with dnd, close subset dialog, formula editor dialog ## * formulavar -- droplist updated with data, with dnd, also has button for foumulat editor ## * datavar -- droplist updated with dnd, when updated chnages droplist in responsevar and formulavar ## * subsetvar -- updated with dnd, has subsetEditor ## * formulaEditor -- how to do? Must have following ## adding binary terms: +, * .... ## grouping via () ## wrapping terms: I(), tsvar(), ... ## how to integrate lm, glm, sspir usages, nlm? ################################################## ## some specific widgets for handling variables ## call this instead of the others ## gvarariables( gvariables = function(variableType=NULL,..., toolkit=guiToolkit()) { if(variableType %in% c("univariate","univariatetable","bivariate","model","lattice")) { tmp = switch(variableType, "univariate" = gunivariate(...,toolkit=toolkit), "univariatetable" = gunivariatetable(...,toolkit=toolkit), "fileurl" = gfileurl(...,toolkit=toolkit), "bivariate" = gbivariate(...,toolkit=toolkit), "model" = gmodel(...,toolkit=toolkit), "lattice" = glattice(...,toolkit=toolkit), "lmer" = glmer(...,toolkit=toolkit) ) return(tmp) } else { ## can't do anything here yet ## expects something so we give back a box return(ggroup(...,toolkit=toolkit)) } } ## For these we return a string ready to go. ## take an idwidget, wrap an argument around it, return as a container ## with value method giving "arg=val" setClass("gAddargANY", representation(argument="character"), contains="gComponentANY" ) addArg = function(argument,widget,container = NULL, toolkit=guiToolkit()) { delete(container,widget) # a hack, take away parent to reparent label = glabel(text=Paste(argument,"= "), container=container) add(container,widget) obj = new("gAddargANY",block=container, widget=widget, toolkit=toolkit, argument=argument) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gAddargANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { val = svalue(obj@widget) arg = obj@argument val = stripWhiteSpace(val) if(val == "") { return(NA) } else if( is(obj@widget,"gEditListANY") || is(obj@widget,"gEditNamedListANY") || arg == "...") { return(val) } else { if(is.null(drop) || drop==FALSE) return(Paste(arg,"=",val)) else return(val) } }) setReplaceMethod(".svalue", signature(toolkit="ANY",obj="gAddargANY"), function(obj, toolkit, index=NULL, ..., value) { svalue(obj@widget) <- value return(obj) }) ## the most basic drop handler basicdrophandler = function(h,...) svalue(h$obj) <- h$dropdata ################################################## ### UNIVARIATE ## returns gedit vaRlue setClass("gUnivariateANY", representation(widgets="list"), contains="gComponentANY" ) gunivariate = function(xlabel="x",container=NULL, ..., toolkit=guiToolkit()) { frame = gframe(text = "data", horizontal=TRUE, container=container, expand=TRUE) font(frame) <- c(weight="bold", size="small") xentry = gedit(text="",width=30, container=frame) # was NULL xarg = addArg(argument=xlabel, xentry, container=frame) obj = new("gUnivariateANY",block=frame, widget=frame, toolkit=toolkit, widgets=list(xarg)) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gUnivariateANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { svalue(obj@widgets[[1]]) }) ################################################## ####################################################################### ## returns gedit value, perhaps in table() setClass("gUnivariateTableANY", representation(widgets="list"), contains="gComponentANY" ) gunivariatetable = function(xlabel="x",container=NULL, ..., toolkit=guiToolkit()) { frame = gframe(text = "data", horizontal=TRUE, container=container, expand=TRUE) font(frame) <- c(weight="bold") xentry = gedit(text="",width=30, container=frame) xarg = addArg(argument=xlabel, xentry, container=frame) glabel("Tabulate data?",container=frame) doTable=gcombobox(c(TRUE,FALSE),container=frame) obj = new("gUnivariateTableANY",block=frame, widget=frame, toolkit=toolkit, widgets=list(x=xarg, doTable=doTable)) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gUnivariateTableANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { vals = svalue(obj@widgets[[1]], drop=TRUE) doTable = as.logical(svalue(obj@widgets[[2]])) if(doTable) vals = paste("table(",vals,")", sep="", collapse="") return(vals) }) ################################################# ################################################# ## a File browser with a switch for wrapping in url ## returns gedit value, perhaps in table() setClass("gFileURLANY", representation(widgets="list"), contains="gComponentANY" ) gfileurl = function(xlabel="file",container=NULL, ..., toolkit=guiToolkit()) { frame = gframe(text = "file", horizontal=TRUE, container=container, expand=TRUE) font(frame) <- c(weight="bold") xentry = gfilebrowse(text="",width=40, container=frame) xarg = addArg(argument=xlabel, xentry, container=frame) glabel("A url?",container=frame) doURL=gcombobox(c(FALSE,TRUE),container=frame) obj = new("gFileURLANY",block=frame, widget=frame, toolkit=toolkit, widgets=list(x=xarg, doURL=doURL)) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gFileURLANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { vals = svalue(obj@widgets[[1]]) doURL = as.logical(svalue(obj@widgets[[2]])) # TRUE of FALSE if(doURL) vals = paste("url(",quoteIfNeeded(vals),")", sep="", collapse="") return(vals) }) ################################################## ## bivariate setClass("gBivariateANY", representation(widgets="list"), contains="gComponentANY" ) gbivariate = function(xlabel = "x", ylabel = "y", container=NULL, ..., toolkit=guiToolkit()) { frame = gframe(text = "data", horizontal=TRUE, container=container, expand=TRUE) font(frame) <- c(weight="bold") xentry = gedit(text="",width=30, container=frame) ## adddroptarget(xentry, handler = basicdrophandler) xarg = addArg(argument=xlabel, xentry, container=frame) yentry = gedit(text="",width=30, container=frame) ## adddroptarget(yentry, handler = basicdrophandler) yarg = addArg(argument=ylabel, yentry, container=frame) obj = new("gBivariateANY",block=frame, widget=frame, toolkit=toolkit, widgets=list(xarg,yarg)) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gBivariateANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { return(PasteWithComma( svalue(obj@widgets[[1]]), # xvalue svalue(obj@widgets[[2]]) # yvalue ) ) }) setReplaceMethod(".svalue", signature(toolkit="ANY",obj="gBivariateANY"), function(obj, toolkit, index=NULL, ..., value) { value = rep(value,2)[1:2] lapply(1:2, function(i) svalue(obj@widgets[[i]]) <- value[i]) return(obj) }) ################################################## ## model formula -- this has drag and drop stuff, and formula editing setClass("gModelANY", representation(widgets="list"), contains="gComponentANY", ) gmodel = function(lattice=FALSE, container=NULL,...,toolkit=guiToolkit()) { ## containers frame = gframe(text = "data", horizontal=FALSE, container=container, expand=TRUE, anchor=c(-1,1)) font(frame) <- c(weight="bold", size="small") ## we have 4 main things: response, predictor(s), data, subset editPredictorHandler = function(h,...) { editFormulaDialog(data=h$action$dataEntry, responsewidget=h$action$responseEntry, predictorwidget=h$action$predictorEntry) } dataDropHandler = function(h,...) { val.str = h$dropdata ## in gWidgetsRGtk2 dnd is a little messy #JV if(getOption("guiToolkit") != "RGtk2") svalue(h$obj) <- val.str ## gets on enter handler? names = try(getNamesofObject(val.str)) if(!inherits(names,"try-error") && !is.null(names)) { ## set dropdown values: responseEntry[] <- names predictorEntry[] <- names if(lattice) conditionEntry[] <- names ## what else? } } dataEnterHandler = function(h,...) { val.str = svalue(h$obj) names = getNamesofObject(val.str) if(!is.null(names)) { ## set dropdown values: responseEntry[] <- names predictorEntry[] <- names if(lattice) conditionEntry[] <- names ## what else? } } ## subsetDropHandler = basicdrophandler editSubsetHandler = function(h,...) { editSubsetDialog(data=h$action$dataEntry, widget=h$action$subsetEntry) } editConditionHandler = function(h,...) { editConditionDialog(data=h$action$dataEntry, widget = h$action$conditionEntry) } ## Build up the widgets now variableNames = c("",getNamesofObject()) tbl = glayout(container=frame, anchor=c(-1,1), width=500,height=100) tbl[1,1] <- (responseEntry = gcombobox(variableNames,width=40,editable=TRUE, container =tbl)) tbl[2,1] <- "response" size(responseEntry) <- c(200, -1) ## add ~ tbl[1,2] <- " ~ " tbl[1,3] <- (predictorEntry = gcombobox(variableNames,width=50, editable=TRUE, container =tbl)) tbl[2,3] <- "predictor(s)" size(predictorEntry) <- c(200, -1) tbl[1,4] <- (predictorEdit = gbutton("edit",container=tbl)) ## lattice has a conditioning variable ## define this even if not needed conditionEntry = NULL if(lattice) { tbl[3,2] <- " | " tbl[3,3] <- (conditionEntry = gcombobox(variableNames, editable=TRUE, container=tbl)) tbl[4,3] <- "conditioning variable(s)" tbl[3,4] <- (conditionEdit = gbutton("edit",container=tbl)) } visible(tbl) <- TRUE ## visual separation gseparator(container=frame) ## Now for data frame tbl = glayout(container=frame, anchor = c(-1,1), width=500,height=100) tbl[1,1, anchor=c(1,0)] = "data=" tbl[1,2, anchor=c(-1,0)] = (dataEntry <- gedit("", container=tbl)) addhandlerchanged(dataEntry, handler = dataEnterHandler) adddroptarget(dataEntry, handler = dataDropHandler) ## subset has extra button for editing tbl[2,1, anchor=c(1,0)] = "subset=" tbl[2,2, anchor=c(-1,0)] = (subsetEntry <- gedit("", container =tbl)) tbl[2,3] = (subsetEdit <- gbutton("edit",container=tbl) ) visible(tbl) <- TRUE # for RGtk2 ## add handlers --after dataEntry is defined addHandlerChanged(predictorEdit, handler=editPredictorHandler, action=list(dataEntry=dataEntry, responseEntry=responseEntry, predictorEntry=predictorEntry)) addHandlerChanged(subsetEdit, handler=editSubsetHandler, action=list( dataEntry=dataEntry, subsetEntry=subsetEntry ) ) if(lattice) { addHandlerChanged(conditionEdit, handler = editConditionHandler, action = list(dataEntry=dataEntry, conditionEntry =conditionEntry)) } obj = new("gModelANY",block=frame,widget=frame, toolkit=toolkit, widgets = list(response = responseEntry, predictor = predictorEntry, data = dataEntry, subset = subsetEntry, lattice = conditionEntry ) ) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gModelANY"), function(obj, toolkit,index=NULL, drop=NULL, ...) { lst = lapply(obj@widgets, function(i) { if(!is.null(i)) svalue(i) }) names(lst) = c("response","predictor","data","subset","lattice")[1:length(lst)] ## return a string of type r ~ p, data=..., subset=... str = with(lst, Paste(response," ~ ",predictor)) if(!is.null(lst$lattice) && lst$lattice != "") str = Paste(str, " | ", lst$lattice) if(lst$data != "") str = PasteWithComma(str,Paste("data=",lst$data)) if(lst$subset != "") str = PasteWithComma(str,Paste("subset=",lst$subset)) return(str) }) setReplaceMethod(".svalue", signature(toolkit="ANY",obj="gModelANY"), function(obj, toolkit, index=NULL, ..., value) { if(is.list(value)) unlist(value) lapply(1:4, function(i) svalue(obj@widjets[[i]]) <- value[i]) return(obj) }) ################################################## ## interface for lattice graphics glattice = function(..., toolkit=guiToolkit()) return(gmodel(lattice = TRUE, ...,toolkit=toolkit)) ################################################## setClass("gLmerANY", representation(formulaEntry="guiWidget", dataEntry="guiWidget"), contains="gComponentANY") ## interface for linear mixed effects models models glmer = function(container=NULL, ..., toolkit=guiToolkit()) { frame = gframe(text = "data", horizontal=FALSE, container=container) font(frame) <- c(weight="bold") tbl = glayout(container=frame) tbl[1,1] = "formula" tbl[1,2] = (formulaEntry <- gedit("", width=40, container =tbl)) tbl[2,1] = "data=" tbl[2,2] = (dataEntry <- gedit("", container =tbl)) visible(tbl) <- TRUE obj = new("gLmerANY",block=frame,widget=frame,toolkit=toolkit, dataEntry = dataEntry, formulaEntry = formulaEntry) return(obj) } setMethod(".svalue", signature(toolkit="ANY",obj="gLmerANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { formulaValue = svalue(obj@formulaEntry) dataValue = svalue(obj@dataEntry) if (formulaValue == "") return("") string = formulaValue if(dataValue != "") string = Paste(string, ", data=",dataValue) return(string) }) ## some special edit fields ## this is used to get "..." into generic widget setClass("gEditListANY", contains="gComponentANY") geditlist = function(...,toolkit=guiToolkit()) { edit = gedit(...,toolkit=toolkit) obj = new("gEditListANY", block=edit@widget@block, widget=edit@widget@widget, toolkit=toolkit) invisible(obj) } setClass("gEditNamedListANY", contains="gComponentANY") geditnamedlist = function(..., toolkit=guiToolkit()) { edit = gedit(...,toolkit=toolkit) obj = new("gEditNamedListANY", block=edit@widget@block, widget=edit@widget@widget, toolkit=toolkit) invisible(obj) } ################################################## ## ## two dialogs for editing ## sample edit Formula dialog, Smilar to one in Splus, but layout is ## not as nice, not quite as feature rich editFormulaDialog = function( data=NULL, # within these variables responsewidget = NULL, # response value predictorwidget = NULL # predictor value ) { ## actually get data, not just a string if(is(data,"guiWidget") || is(data,"gComponentANY")) { data = svalue(data) dataName = deparse(substitute(data)) } if(is.character(data) && length(data) == 1) { dataName = data data = getObjectFromString(data) } if(is.na(data) || is.null(data)) { warning("Can't find data set") return(NA) } ## coerce data if possible if(!is.data.frame(data)) { tmp = try(as.data.frame(data), silent=TRUE) if(inherits(tmp,"try-error")) { warning("gtable shows data frames of vectors") return(NA) } data = tmp } varNames = names(data) ## define key widgets ## Set up the window ## main window win = gwindow("Edit model formula values") group = ggroup(horizontal=FALSE, container=win) datagroup = ggroup(container=group) size(datagroup) <- c(300,200) glabel("Dataset: ", container=datagroup) tmp = glabel(dataName, container=datagroup); font(tmp) <- c(weight="bold") addSpace(datagroup, 10) variables = gtable(varNames,multiple=TRUE, container =datagroup, expand=TRUE) gseparator(container =group) ## buttons buttonGroup = ggroup(container=group) glabel("Actions:", container=buttonGroup) tbl = glayout(container =buttonGroup, expand=TRUE) tbl[1,1,anchor=c(-1,0)] = (addresponse <- gbutton("Response",container =tbl)) tbl[1,2,anchor=c(-1,0)] = (addterm <- gbutton("+ (main effect)",container =tbl)) tbl[2,1,anchor=c(-1,0)] = (addwithin <- gbutton(": (interaction)",container =tbl)) tbl[2,2,anchor=c(-1,0)] = (addinteraction <- gbutton("* (main + interaction)",container =tbl)) tbl[3,1,anchor=c(-1,0)] = (addsecondpowers <- gbutton("^2 (second-order)",container =tbl)) tbl[3,2,anchor=c(-1,0)] = (subtractintercept <- gbutton("remove intercept",container =tbl)) visible(tbl) <- TRUE gseparator(container =group) tbl = glayout(container=group) response = gedit(svalue(responsewidget),container =tbl) predictor = gedit(svalue(predictorwidget), container =tbl) tbl[1,1] <- response tbl[1,2] <- glabel(" ~ ",container =tbl) tbl[1,3:6] <- predictor tbl[2,1] <- "response" tbl[2,3:6] <- "predictor formula" visible(tbl) <- TRUE buttonbox = ggroup(container=group) addSpring(buttonbox) okbutton = gbutton("ok", container =buttonbox) addSpace(buttonbox,15) clearbutton = gbutton("clear", container =buttonbox) cancelbutton = gbutton("cancel", container =buttonbox) ## Now add handlers addhandlerclicked(addresponse, handler=function(h,...) { vals = svalue(variables) if(!is.null(vals)) { svalue(response) <- vals[1] } }) addhandlerclicked(addinteraction,handler=function(h,...) { vars = svalue(variables) if(!is.null(vars)) { oldval = svalue(predictor) if(!is.null(oldval) && oldval !="") oldval = Paste(oldval, " + ") else oldval = "" svalue(predictor) <- Paste(oldval, paste(vars, sep="", collapse=" * ")) } }) addhandlerclicked(addterm,handler=function(h,...) { vars = svalue(variables) if(!is.null(vars)) { oldval = svalue(predictor) if(!is.null(oldval) && oldval !="") oldval = Paste(oldval, " + ") else oldval = "" svalue(predictor) <- Paste(oldval, paste(vars, sep="", collapse=" + ")) } }) addhandlerclicked(addsecondpowers,handler=function(h,...) { vars = svalue(variables) if(!is.null(vars)) { oldval = svalue(predictor) if(!is.null(oldval) && oldval !="") oldval = Paste(oldval, " + ") else oldval = "" svalue(predictor) <- Paste(oldval, " (", paste(vars, sep="", collapse=" + "), ")^2") } }) addhandlerclicked(addwithin,handler=function(h,...) { vars = svalue(variables) if(!is.null(vars)) { oldval = svalue(predictor) if(!is.null(oldval) && oldval !="") oldval = Paste(oldval, " + ") else oldval = "" svalue(predictor) <- Paste(oldval, paste(vars, sep="", collapse=":") ) } }) addhandlerclicked(subtractintercept,handler=function(h,...) { svalue(predictor) <- Paste(svalue(predictor), " -1") }) addhandlerclicked(okbutton, handler = function(h,...) { svalue(responsewidget) <- svalue(response) svalue(predictorwidget) <- svalue(predictor) dispose(win) }) addhandlerclicked(clearbutton, handler=function(h,...) { svalue(response) <- "" svalue(predictor) <- "" }) addhandlerclicked(cancelbutton,handler=function(h,...) { dispose(win) }) } editSubsetDialog = function( data=NULL, widget = NULL # what to write to, start with ) { ## get data values if(is(data,"guiComponent") || is(data,"gComponentANY")) { data = svalue(data) } if(is.character(data)) { if(data == "") { warning("A data set needs to be set") return() } dataName = data data = svalue(data) } else { dataName = deparse(substitute(data)) } if(!is.data.frame(data)) { tmp = try(as.data.frame(data), silent=TRUE) if(inherits(tmp,"try-error")) { warning("gtable shows data frames of vectors") return(NA) } data = tmp } varNames = names(data) ## main widgets # preview = gtable(head(data)) ## layout win = gwindow("Edit subset value") # main window group = ggroup(horizontal=FALSE, container=win) glabel(Paste("Data set:", dataName,""), container=group) tbl = glayout(container=group) tbl[1,1] <- (andOrPopup = gcombobox(c("","&","|"), container =tbl)) tbl[1,2] <- (notPopup = gcombobox(c("","!"), container =tbl)) tbl[1,3] <- (var1 = gcombobox(varNames, editable=TRUE, container =tbl)) tbl[1,4] <- (logicalPopup = gcombobox(c("","<","<=","==","!=",">=",">","%in%"), container =tbl)) tbl[1,5] <- (var2 = gcombobox(varNames, editable = TRUE, container =tbl)) tbl[2,1] <- "join with" tbl[2,2] <- "negate" tbl[2,3] <- "" tbl[2,4] <- "compare with" tbl[2,5] <- "" visible(tbl) <- TRUE buttonGroup = ggroup(container=group) addSpring(buttonGroup) addButton = gbutton("add", container =buttonGroup) addSpace(buttonGroup,10) clearButton = gbutton("clear",container =buttonGroup) outputGroup = ggroup(container=group) glabel("Subset by",container=outputGroup) output = glabel("", container =group) font(output) <- c(weight="bold") # make bold status = glabel("",container =group) gseparator(container=group) spacingGroup = ggroup(container=group) glabel("Preview:", container=spacingGroup) addSpring(spacingGroup) preview = gtable(data, container =group, expand=TRUE) enabled(preview) <- FALSE buttonGroup = ggroup(container=group) addSpring(buttonGroup) okButton = gbutton("ok", container =buttonGroup) addSpace(buttonGroup,10) cancelButton = gbutton("cancel", container =buttonGroup) ## now give some actions addHandlerAction = function(h,...) { str = Paste( svalue(var1), svalue(logicalPopup), svalue(var2) ) if(!is.null(svalue(notPopup)) && length(svalue(notPopup)) > 0 && svalue(notPopup) == "!") str = Paste("!( ",str," )") ## error check tmp = try(rpel(Paste("subset(data,subset=",str,")"), envir=environment(NULL))) if(! inherits(tmp,"try-error")) { combine = svalue(andOrPopup) if(is.null(combine)) combine = "" previous = svalue(output) if(length(previous) == 0 || nchar(previous) == 0) { combine=""; previous="" } if(nchar(previous) > 0 && combine == "") { svalue(status) <-"You need an operator to combine terms" return(FALSE) } svalue(output) <- Paste(previous," ",combine," ",str) svalue(status) <- "" ## update preview subsetVal = svalue(output) tmpVals = rpel(Paste("head(subset(data,subset=",subsetVal,"))"), envir=environment(NULL)) preview[,] = tmpVals } else { svalue(status) <- Paste(str," failed") } } ## when logical is %in$ and leftside if factor, we can do some business addhandlerchanged(logicalPopup,handler = function(h,...) { ## check that all conditions are met if(length(svalue(logicalPopup)) > 0 && svalue(logicalPopup) == "%in%") { varName = svalue(var1) var = getObjectFromString(Paste(dataName,"$",varName)) if(is.factor(var)) { varLevels = levels(var) selectVectorEntriesDialog(varLevels, var2) } } } ) addhandlerclicked(clearButton, handler = function(h,...) { svalue(output) <- "" svalue(status) <- "" preview[] <- head(data) }) addhandlerclicked(addButton, handler=addHandlerAction) addhandlerclicked(okButton, handler = function(h,...) { outputValue = svalue(output) ## strip leading spaces svalue(widget) <- sub("^ +","",outputValue) dispose(win) }) addhandlerclicked(cancelButton, handler=function(h,...) { dispose(win) }) } ## add terms editConditionDialog <- function(data,widget) { data <- svalue(data) if(is.na(data) || is.null(data)) { warning("empty dataset") return() } else if(data == "") { varNames = ls(envir=.GlobalEnv) } else { ## get data values if(is(data,"gComponentANY")) { data = svalue(data) } if(is.character(data)) { dataName = data data = rpel(Paste("get(\"",data,"\")", sep=" ")) } else { dataName = deparse(substitute(data)) } if(!is.data.frame(data)) { tmp = try(as.data.frame(data), silent=TRUE) if(inherits(tmp,"try-error")) { warning("gtable shows data frames of vectors") return(NA) } data = tmp } varNames = names(data) } win = gwindow("Select variables for conditioning variable", visible=TRUE) group = ggroup(horizontal=FALSE, container=win) vars = gtable(varNames, multiple=TRUE, handler=function(h,...) { values = svalue(h$obj) if(length(values) > 0) { out = paste(values, collapse=" + ") svalue(widget) <- out } dispose(win) }, container =group, expand=TRUE) buttonGroup = ggroup(container=group) addSpring(buttonGroup) gbutton("ok",container=buttonGroup, action=vars, handler=function(h,...) { values = svalue(h$action) if(length(values) > 0) { out = paste(values, collapse=" + ") svalue(widget) <- out } dispose(win) }) gbutton("close",container=buttonGroup, handler = function(h,...) dispose(win)) status = gstatusbar("Select one or more variables to condition by.", container=group) } ## select asks user for which columns to consider editSelectDialog = function(data,widget) { ## get data values if(is(data,"gComponentANY")) { data = svalue(data) if(data == "") { warning("A data set needs to be set") return() } } if(is.character(data)) { if(data == "") { warning("A data set needs to be set") return() } dataName = data data = rpel(Paste("get(\"",data,"\")", sep=" ")) } else { dataName = deparse(substitute(data)) } if(!is.data.frame(data)) { tmp = try(as.data.frame(data), silent=TRUE) if(inherits(tmp,"try-error")) { warning("gtable shows data frames of vectors") return(NA) } data = tmp } varNames = names(data) win <- gwindow("Select variables", visible=TRUE) group <- ggroup(horizontal=FALSE,container=win) frame <- gframe("Select all the desired variables", container=group, expand=TRUE) font(frame) <- c(weight="bold") varList <- gtable(varNames, multiple=TRUE, container=frame, expand=TRUE) buttonGroup = ggroup(container=group) addSpring(buttonGroup) submitButton = gbutton("submit",container=buttonGroup, handler = function(h,...) { values = svalue(varList) ## wrap it up str = Paste("c(",paste(sapply(values,function(str) paste("'",str,"'",sep="")),sep=" ",collapse=", "),")") svalue(widget) <- str ## lclose dialog dispose(win) }) } ## put values into a vector with paste selectVectorEntriesDialog <- function(vals, widget) { win=gwindow("Select values", visible=T) group = ggroup(horizontal = FALSE, container=win) varNamesList = gtable(vals, multiple = TRUE, group, expand=TRUE) buttonGroup = ggroup(container=group) addSpring(buttonGroup) okButton = gbutton("ok",container=buttonGroup) cancelButton = gbutton("cancel", container=buttonGroup) addhandlerclicked(cancelButton, handler = function(h,...) { dispose(win) }) addhandlerclicked(okButton, handler = function(h,...) { varNames = svalue(varNamesList) varNamesAsString = Paste("c(\"",paste(varNames,sep="'",collapse="\",\""),"\")") svalue(widget) <- varNamesAsString ## tidy up dispose(win) }) } gWidgets/R/ghelp.R0000644000176000001440000005046213650756705013527 0ustar ripleyusers##' @include guiComponents.R ## ghelp relies on unexported values :::. It should be treated with caution. Here we put into ## eval/parse hack to get it passed R CMD check. XXX SHould deprecate ##' Widget to provide interface to help system setClass("gHelp", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for help system widget ##' ##' @export ghelp <- function( topic = NULL, package = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .ghelp (toolkit, topic=topic, package=package, container=container ,... ) obj <- new( 'gHelp',widget=widget,toolkit=toolkit) return(obj) } ##' API ##' add, character -- add page character=c(topic), c(topic,package) "package:::topic" ##' add, list -- add page, list(topic, package=NULL) ##' svalue: return list(topic=topic, package=package) ##' length: number of pages ##' dispose: remove current page ##' generic for toolkit dispatch ##' @alias ghelp setGeneric( '.ghelp' , function(toolkit, topic = NULL, package = NULL, container = NULL, ... ) standardGeneric( '.ghelp' )) ################################################## ## ANY imlementation setClass("gHelpANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) setMethod(".ghelp", signature(toolkit="ANY"), function(toolkit, topic=NULL, package=NULL, container = NULL, ...) { # passed to gnotebook force(toolkit) ## check if newversion of R, if so, we con't do a thing but return a label if(!getRversion() >= "2.11.0" && getRversion() < "2.11.0") { gwCat("Needs a new version of R to work.\n") glabel("ghelp", container=container) } nb <- gnotebook(container=container, closebuttons=TRUE, ...) obj <- new("gHelpANY", block=nb, widget=nb, toolkit=toolkit) if(!is.null(topic)) .add(obj, toolkit, value = list(topic=topic, package=package)) invisible(obj) }) ################################################## ## gHelp methods ## workhorse is add -- value is either ## just a topic (not a list), or a list with components topic, package setMethod(".add", signature(toolkit="ANY",obj="gHelpANY", value="character"), function(obj, toolkit, value, ...) { if(length(grep(":",value)) > 0) { # "stats:::t.test" works here tmp = unlist(strsplit(value, ":+")) package = tmp[1] topic = tmp[2] } else { topic = value package = NULL } .add(obj, toolkit, list(topic=topic, package=package)) }) ##' add a page to the help notebook ##' @param obj ghelp object ##' @param toolkit toolkit ##' @param value a list with component topic and value setMethod(".add", signature(toolkit="ANY",obj="gHelpANY", value="list"), function(obj, toolkit, value, ...) { topic <- value$topic package <- value$package nb <- obj@widget ## error check if(!is.character(topic) || length(topic) > 1 || length(topic) == 0) { warning(sprintf("Adding to ghelp needs a valid topic. You tried %s.\n",topic)) return(NULL) } l <- .findHelpPage(topic, package) x <- l$x topic <- l$topic; package <- l$package if(!is.null(x)) { ## are we already present? if(n <- .length(obj, toolkit)) { for(i in 1:n) { l <- list(topic=tag(nb[i],"topic"), package=tag(nb[i],"package")) if(l$topic == topic && ( (is.null(package) | is.null(l$package)) || l$package == package)) { svalue(nb) <- i return(NULL) } } } ## good to go nb <- obj@widget t <- gtext(container=nb, label=topic, expand=TRUE) tag(t, "topic") <- topic tag(t, "pacakge") <- package svalue(nb) <- length(nb) .insertHelpPage(t, x) } return(NULL) }) ##' returns list of topic and package of current page setMethod(".svalue", signature(toolkit="ANY",obj="gHelpANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { nb <- obj@widget if(n <- length(nb) == 0) return(NULL) if(is.null(index)) index <- svalue(nb) else index <- min(1, max(n, as.integer(index))) page <- nb[index] l <- list(topic=tag(page, "topic"), package=tag(page, "package")) return(l) }) ##' number of pages in notebook setMethod(".length", signature(toolkit="ANY",x="gHelpANY"), function(x, toolkit) { length(x@widget) }) ##' dispose of current page setMethod(".dispose", signature(toolkit="ANY",obj="gHelpANY"), function(obj, toolkit, ...) { dispose(obj@widget) }) ### Helper functions for "add" ##' return help page a set of lines .findHelpPage <- function(topic, package=NULL) { l <- list(topic=topic) if(!is.null(package)) l$package <- package out <- do.call("help", l) if(length(out) == 0) return(NULL) pkgname <- basename(dirname(dirname(out))) ## thanks to Josef L for this help.txt <- "" ## keep R CMD check happy help.con <- textConnection("help.txt", "w", local = TRUE) x <- eval(parse(text=sprintf("utils:::%s", ".getHelpFile(out)"))) tools::Rd2txt(x, out=help.con, package=pkgname, width=80L) close(help.con) return(list(x=help.txt,topic=topic, package=pkgname)) } ##' insert help page into text object ##' makes bold if speedy enough .insertHelpPage <- function(obj, x) { isSlow <- obj@toolkit@toolkit == "tcltk" || obj@toolkit@toolkit == "RGtk2" dispose(obj) # clear out <- c() for(i in x) { if(grepl("^_\b",i)) { if(isSlow) out <- c(out, gsub("_\b","",i)) else insert(obj, gsub("_\b","",i), font.attr=c(weight="bold")) } else { if(isSlow) out <- c(out,i) else insert(obj, i,font.attr=c(weight="normal")) } } if(isSlow) svalue(obj) <- out else insert(obj, "", do.newline=FALSE, where="beginning") } ################################################## ## helpers getPossiblePackages = function(topic) { possiblePackages = c() ## find all packages lib.loc <- .libPaths() packages <- .packages(all.available = TRUE, lib.loc = lib.loc) for (lib in lib.loc) { for (pkg in packages) { dir <- system.file(package = pkg, lib.loc = lib) path = eval(parse(text=sprintf("utils:::%s(topic, dir, \"AnIndex\", \"help\")","index.search"))) if(path != "") possiblePackages = c(possiblePackages, pkg) } } if(length(possiblePackages) == 0) { warning("Adios, can't find a package to match ",topic,"\n") return() } return(possiblePackages) } ################################################## ## This just pops up a window to show the argument from a help page ## Hack to open up help page to the argument showHelpAtArgument = function(argument, topic, package=NULL, width=600, height=250) { if(missing(argument) || missing(topic)) return() if(is.null(package)) { possiblePackages = getPossiblePackages(topic) if(length(possiblePackages) > 0) { package = possiblePackages } else { warning(Paste("Can't find a package containing", topic,"\n")) return() } } ## the widget win=gwindow(Paste("Help on argument: ",topic), visible=FALSE) # set to visible if one is found group = ggroup(horizontal=FALSE, container=win) textwindow = gtext("", container=group, expand=TRUE) size(textwindow) <- c(width,height) for(pkg in package) { ## helpFile = system.file("help",topic,package=pkg) helpFile = help(topic, package=force(pkg), verbose=TRUE)[1] if(helpFile != "") { text = readLines(helpFile) text = sapply(text, function(i) gsub("\\_\\\b","",i)) argPosition = grep(Paste(argument,": "), text) if(length(argPosition) == 0) { next } else { argPosition = argPosition[1] - 1 ##Found one visible(win) <- TRUE # show window } add(textwindow,Paste("From package:",pkg), font.attr=c(weight="bold")) ## add first line (it has a :) add(textwindow,text[argPosition+1],font.attr=c(weight="bold",color="blue")) ## add until a : i = 2; n = length(text) while(length(grep(":",text[argPosition+i])) == 0 && (argPosition + i) <= n ) { add(textwindow,text[argPosition+i],font.attr=c(weight="bold",color="blue")) i = i + 1 } add(textwindow,"\n") } } ## close button buttonGroup = ggroup(container=group) addSpring(buttonGroup) gbutton("cancel", container=buttonGroup, handler = function(h,...) dispose(h$obj)) } ################################################## ## build on ghelp widget to make a browser with search, ## simpler than old pmg.helpBrowser. Break that into components ################################################## ## ghelpbrowser ##' Widget to provide interface to help system setClass("gHelpBrowser", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' help browser widget, stand alone window ##' ##' @export ghelpbrowser <- function( title = "Help browser", maxTerms = 100, width = 1000, height = 600 , ..., toolkit=guiToolkit()) { widget <- .ghelpbrowser(toolkit, title=title, maxTerms=maxTerms, width=width ) obj <- new( 'gHelpBrowser',widget=widget,toolkit=toolkit) return(obj) } ##' API: ##' visible<-, logical. Display or hide sidebar ##' size<-, set size of window ##' size, size of window ##' generic for toolkit dispatch ##' @alias ghelpbrowser setGeneric( '.ghelpbrowser' , function(toolkit, title = "Help browser", maxTerms = 100, width = 1000, height = 600 ) standardGeneric( '.ghelpbrowser' )) ## a notebook for holding help pages setClass("gHelpbrowserANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) ################################################## ## build on ghelp widget to make a browser with search, ## simpler than old pmg.helpBrowser. Break that into components ## a notebook for holding help pages setClass("gHelpbrowserANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) setMethod(".ghelpbrowser", signature(toolkit="ANY"), function(toolkit, title = "Help browser", maxTerms=100, width=1000, height=600) { force(toolkit) ## Main widget helpBrowser <- gwindow(gettext("Help browser"), visible=FALSE) ## we need to check what toolkit toolkitType <- helpBrowser@toolkit@toolkit # hackery ##' layout for help search (apropos, pattern) helpSearch <- function(container, ...) { g <- ggroup(horizontal=FALSE, expand=TRUE, container=container, ...) sg <- ggroup(container=g, horizontal=TRUE, fill="x", ...) cb <- gcombobox(c("Apropos", "Pattern"), container=sg) e <- gedit("", container=sg, expand=TRUE, fill="x") sr <- gtable(data.frame("Function"=character(0), Package=character(0), Title=character(0), stringsAsFactors=FALSE), container=g, expand=TRUE, fill="both") addHandlerClicked(sr, handler=function(h,...) { sel <- svalue(h$obj, drop=FALSE) if(!is.null(sel)) { l <- list(topic=sel[[1]], package=sel[[2]]) add(helpWidget, l) } }) searchResultsApropos = function(query) { out = help.search(apropos=query, ignore.case = TRUE) out = out$matches if(nrow(out) > 0) { out = out[1:min(nrow(out),maxTerms),c(1,3,2), drop=FALSE] } else { out = c("no matches","","") } colnames(out) = c("Function","Package","Title") out = as.data.frame(out) for(j in 1:3) out[,j] <- as.character(out[,j]) # avoid factors return(out) } ##' results for help.search searchResultsHelpSearch = function(query) { out = help.search(pattern=query, ignore.case = TRUE) out = out$matches if(nrow(out) > 0) { out = out[1:min(nrow(out),maxTerms),c(1,3,2), drop=FALSE] } else { out = c("no matches","","") } colnames(out) = c("Function","Package","Title") out = as.data.frame(out) for(j in 1:3) out[,j] <- as.character(out[,j]) # avoid factors return(out) } addHandlerChanged(e, handler=function(h,...) { query <- svalue(h$obj) toolkitType <- svalue(cb, index=1) out <- switch(toolkitType, searchResultsApropos(query), searchResultsHelpSearch(query)) sr[] <- out }) } browsePackages <- function(container, ...) { getContentsOfPackage <- function(package) { ## return a data frame with entry keywords description path <- system.file("help", package = package) contents <- readRDS(sub("/help", "/Meta/Rd.rds", path, fixed = TRUE)) return(data.frame(Entry=contents[,'Name'], Keywords=sapply(contents[,"Keywords"], paste, collapse=", "), Description=contents[,'Title'], stringsAsFactors = FALSE)) } emptyDf <- data.frame(Entry=character(0), Keywords=character(0), Description=character(0), stringsAsFactors=FALSE) allPackages <- .packages(all.available=TRUE) curPackage <- NULL g <- ggroup(container=container, horizontal=FALSE, expand=TRUE, ...) g1 <- ggroup(container=g) glabel("Package:", container=g1, anchor=c(1,0)) e <- gedit("", container=g1, anchor=c(-1,0), handler=function(h,...) { val <- svalue(h$obj) if(val %in% allPackages) { curPackage <<- val contents <- getContentsOfPackage(val) fnList[] <- contents } else { curPackage <<- NULL fnList[] <- emptyDf } }) e[] <- allPackages fnList <- gtable(emptyDf, container=g, expand=TRUE) addHandlerClicked(fnList, handler=function(h,...) { topic <- svalue(h$obj) if(nchar(topic)) add(helpWidget, list(topic=topic, package=curPackage)) }) } ##' layout the search pane area layoutSearch <- function(container) { layoutNb <- gnotebook(container=container, expand=TRUE) helpSearch(container=layoutNb, label="Help search") browsePackages(container=layoutNb, label="Browse packages") svalue(layoutNb) <- 1 # first tab } ##' layout the help pane area layoutHelp <- function(container) { tb <- ggroup(container=container, horizontal=TRUE, fill="x") glabel("Help for:", container=tb, anchor=c(1,0)) gedit("", container=tb, anchor=c(-1, 0), handler=function(h,...) { val <- svalue(h$obj) add(helpWidget, val) }) if(toolkitType == "tcltk") { ## dispose if tcltk, otherweise close buttons work gseparator(horizontal=FALSE, container=tb) d <- gbutton("dispose", container=tb, handler=function(h,...) { dispose(helpWidget) }) } if(!toolkitType == "Qt") { ## had errors with running withi handler gbutton("Example", container=tb, handler=function(h,...) { page <- helpWidget[svalue(helpWidget)] do.call("example", list(topic=tag(page, "topic"), package=tag(page, "package"))) }) } addSpring(tb) searchCb <<- gcheckbox("Search box", container=tb, handler=function(h,...) { visible(obj) <- svalue(h$obj) }) helpWidget <<- ghelp(container=container, expand=TRUE, fill="both") } ## widgets pg <- gpanedgroup(container=helpBrowser, horizontal=TRUE) if(toolkitType == "RGtk2") { searchPane <- ggroup(horizontal=FALSE, container=pg) helpPane <- ggroup(horizontal=FALSE, container=pg) } else { helpPane <- ggroup(horizontal=FALSE, container=pg) searchPane <- ggroup(horizontal=FALSE, container=pg) } helpWidget <- NULL # defined in layoutHelp searchCb <- NULL layoutSearch(searchPane) layoutHelp(helpPane) ## show gwindow obj <- new("gHelpbrowserANY", block= helpBrowser, widget=helpBrowser, toolkit=toolkit) tag(obj, "pg") <- pg tag(obj, "searchCb") <- searchCb tag(obj, "toolkitType") <- toolkitType visible(helpBrowser) <- TRUE size(obj) <- c(width, height) visible(obj) <- FALSE # hide sidebar return(obj) }) ##' toggle sidebar setReplaceMethod(".visible", signature(toolkit="ANY",obj="gHelpbrowserANY", value="logical"), function(obj, toolkit, ..., value) { cb <- tag(obj, "searchCb"); svalue(cb) <- value toolkitType <- tag(obj, "toolkitType") pg <- tag(obj, "pg") if(value) { val <- tag(pg, "lastPosition") if(is.null(val) || is.nan(val)) val <- 0.6 val <- max(min(0.75, val), 0.6) if(toolkitType == "RGtk2") val <- 1 - val svalue(pg) <- val } else { tag(pg, "lastPosition") <- svalue(pg) svalue(pg) <- ifelse(toolkitType=="RGtk2",0,1) } obj }) ##' report widget size setMethod(".size", signature(toolkit="ANY",obj="gHelpbrowserANY"), function(obj, toolkit, ...) { w <- obj@widget size(w) }) ##' Set widget size setReplaceMethod(".size", signature(toolkit="ANY",obj="gHelpbrowserANY", value="numeric"), function(obj, toolkit, ..., value) { w <- obj@widget size(w) <- value obj }) gWidgets/R/guiContainer.R0000644000176000001440000000464211436312640015040 0ustar ripleyusers##' @include guiWidget.R ##' ##' A subclass of guiWidget to hold containers setClass("guiContainer", contains="guiWidget", prototype=prototype(new("guiWidget")) ) ## define a subclass setClass("gContainerANY", contains="gWidgetANY", prototype=prototype(new("gWidgetANY")) ) ################# methods ################################# ################## add ################################ ##' Generic for adding child widget to parent container setGeneric("add",function(obj,value, ...) standardGeneric("add")) ##' method for adding child to a container setMethod("add",signature(obj="guiContainer"), function(obj, value, ...) { toolkit = obj@toolkit ladd <- function(obj, value, ...,do.newline, font.attr, where) .add(obj@widget, obj@toolkit, value, ...) ladd(obj, value,...) }) ## deprecated ##' ## setMethod("add",signature(obj="guiWidget"), ## function(obj, value, ...) { ## toolkit = obj@toolkit ## .add(obj@widget, toolkit,value,...) ## }) ## setMethod("add",signature(obj="guiComponent"), ## function(obj, value, ...) { ## toolkit = obj@toolkit ## ladd <- function(obj,value, ..., label, name, override.closebuttons, index, pageno, markup, anchor, expand) .add(obj@widget,obj@toolkit,value,...) ## ladd(obj,value,...) ## }) ##' dispatch with toolkit ##' @alias add setGeneric(".add",function(obj, toolkit,value,...) standardGeneric(".add")) ##' Generic to delete child widget from parent setGeneric("delete",function(obj,widget, ...) standardGeneric("delete")) ##' Delete method for containers setMethod("delete",signature(obj="guiContainer"), function(obj, widget, ...) { toolkit = obj@toolkit .delete(obj@widget,toolkit,widget,...) }) ##' dispatch with toolkit ##' @alias delete setGeneric(".delete",function(obj, toolkit,widget,...) standardGeneric(".delete")) ## dispose setGeneric("dispose",function(obj, ...) standardGeneric("dispose")) ## add generic for Containers and sometimes widgets setMethod("dispose",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .dispose(obj@widget, toolkit,...) }) ## dispatch with toolkit setGeneric(".dispose",function(obj,toolkit,...) standardGeneric(".dispose")) gWidgets/R/toolkitClasses.R0000644000176000001440000000664111731167335015424 0ustar ripleyusers##' A class to record the toolkit a gui object uses setClass("guiWidgetsToolkit", representation(toolkit="character"), prototype(toolkit="") ) ##' toolkit class for RGtk2 setClass("guiWidgetsToolkitRGtk2", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ##' toolkit class for rJava setClass("guiWidgetsToolkitrJava", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ##' toolkit class for SJava setClass("guiWidgetsToolkitSJava", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ##' toolkit class for tcltk setClass("guiWidgetsToolkittcltk", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ##' toolkit class for RwxWidgets setClass("guiWidgetsToolkitRwxWidgets", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ##' toolkit class for qtbase setClass("guiWidgetsToolkitQt", contains="guiWidgetsToolkit", prototype=prototype(new("guiWidgetsToolkit")) ) ################################################## ##' all packages that are registered with gWidgets. Used if guiToolkit not specified registered_packages <- c("gWidgetsRGtk2", "gWidgetstcltk", "gWidgetsQt", "gWidgetsrJava", "gWidgetsRwxWidgets") ##' set or get the current toolkit for gWidgets guiToolkit <- function(name=NULL) { ## plan, if name is NULL, and options("guiToolkit") NULL then we popup a menu ## with choices coming from all installed packages named gWidgetsXXXX ## when a name is selected, we require the package gWidgets+name if(is.null(name)) { ## try to get from inheritance, then get from option x = try(get("toolkit", inherits=TRUE), silent=TRUE) if(!inherits(x,"try-error")) { ## check that toolkit is of guiWidgets type x = try("x@toolkit", silent=TRUE) if(!inherits(x,"try-error")) name = x else name = getOption("guiToolkit") } else { name = getOption("guiToolkit") } } if(!is.null(name) && is.na(name)) return(NULL) # use NA to override choice ## no if it is null, we have to find the possible choices if(is.null(name)) { f <- function(x) !inherits(try(find.package(x), silent=TRUE), "try-error") choices <- Filter(f, registered_packages) if(interactive()) { if(length(choices) == 0) { warning("No toolkits installed") return(NULL) } else if(length(choices) == 1) { theChoice = choices } else { theChoice = menu(choices, title="Select a GUI toolkit") if(theChoice == 0) { warning("No toolkit loaded") return(NULL) } else { theChoice = choices[theChoice] } } ## go with theChoice name = gsub("^gWidgets","",theChoice) options("guiToolkit"=name) } else { ## not interactive return(NULL) } } ## require the package require(paste("gWidgets",name,sep=""), character.only=TRUE) ## we return an instance of the toolkit class obj = new(paste("guiWidgetsToolkit",name,sep=""), toolkit = name) return(obj) } ##' Which toolkit are we using? ##' ##' @return string of toolkit (RGtk2, tcltk, Qt, ???) ##' @export gtoolkit <- function() { obj <- guiToolkit() obj@toolkit } gWidgets/R/guiWidget.R0000644000176000001440000005347112313662440014346 0ustar ripleyusers##' @include toolkitClasses.R ##' ##' Basic class for gWidgets objects setClass("guiWidget", representation( toolkit="guiWidgetsToolkit", widget="ANY" # could be RGtkObject, TclObject,.... ), prototype( toolkit =guiToolkit(), widget=NULL ) ) ##' Subclass of gWidgets with NULL possibility setClassUnion("guiWidgetOrNULL", c("NULL","guiWidget")) ##' for ANY toolkit ##' ##' @export setClass("gWidgetANY", representation( toolkit="guiWidgetsToolkit", widget="ANY", # could be RGtkObject, TclObject,.... block="ANY", ID = "numeric" ), prototype( toolkit =guiToolkit(), widget=NULL, block = NULL, ID = getNewID() ) ) ################################################## ## methods ################ show ################################## ##' show method for guiWidget objects ##' ##' @param object guiWidget object to show ##' @return NULL, called to print summary of object ##' @export setMethod("show",signature(object="guiWidget"), function(object) { cat("guiWidget of type:", class(object@widget), "for toolkit:", class(object@toolkit), "\n") }) ################## svalue ################################ ##' generic for selected value, svalue ##' ##' The \code{svalue} method returns the main property of a widget. This of course is context specific. ##' @param obj guiWidget object ##' @param index for selection widgets this is set to decide if value or index should be returned ##' @param drop for selection widgets do we return data frame or ##' vector (if possible). For text widgets, do we return entire text ##' or just selected text ##' @return main value of object ##' @export setGeneric("svalue",function(obj, index=NULL, drop=NULL,...) standardGeneric("svalue")) ##' base svalue method ##' ##' @inheritParams svalue ##' @export setMethod("svalue",signature(obj="guiWidget"), function(obj, index=NULL, drop=NULL, ... ) { toolkit = obj@toolkit val <- .svalue(obj@widget, toolkit, ...,index=index, drop=drop) if(is.logical(index) && index) return(as.integer(val)) ## do we have coercewith? ## we check lots of ways, these should just be slots, someday... coercewith <- NULL if(methods::.hasSlot(obj@widget, "coercewith")) coercewith <- obj@widget@coercewith if(is.null(coercewith)) coercewith <- tag(obj, "coercewith") if(is.null(coercewith)) coercewith <- tag(obj, "coerce.with") ## now return if(is.null(coercewith)) return(val) if(is.character(coercewith)) coercewith <- get(coercewith, inherits=TRUE) if(!is.function(coercewith)) return(val) ## return coerced value coercewith(val) }) ##' svalue method for numeric variables setMethod("svalue",signature(obj="numeric"), function(obj, index=NULL, drop=NULL, ... ) { return(obj) }) ##' svalue method for character data setMethod("svalue",signature(obj="character"), function(obj, index=NULL, drop=NULL, ... ) { if(length(obj) == 1) return(get(obj, envir=.GlobalEnv)) else return(obj) }) ##' package generic has toolkit, object to dispatch on ##' @alias svalue setGeneric(".svalue",function(obj, toolkit, index=NULL, drop=NULL, ...) standardGeneric(".svalue")) ################# svalue<- ################################# ##' svalue<- generic ##' ##' Method for setting main property of a widget ##' @param obj guiWidget object ##' @param index For selection widgets one can set by index or by value ##' @param ... generally ignored, but some widgets use this to pass in extra values. See toolkit documentation ##' @param value new value for main property of widget ##' @return called for its side effect. Whether the "change" handler is called is toolkit and widget dependent. ##' @export setGeneric("svalue<-",function(obj, index=NULL, ...,value) standardGeneric("svalue<-")) ##' svalue method for any widget setReplaceMethod("svalue",signature(obj="guiWidget"), function(obj, index=NULL, ...,value) { toolkit = obj@toolkit .svalue(obj@widget, toolkit, index=index, ...) <- value obj }) ##' dispatch to toolkit ##' @alias svalue<- setGeneric(".svalue<-",function(obj, toolkit, index=NULL, ..., value) standardGeneric(".svalue<-")) ############### [ ################################### ##' [ method for selection widgetgs in guiWidget. ##' ##' Method to refer to objects to select from ##' @param x guiWidget selection widget object ##' @param i index of vector, or row ##' @param j index of column, if possible ##' @param drop logical indicating if values should be dropped, when sensible ##' @return returns vector or data frame of values ##' @export setMethod("[", signature(x="guiWidget"), function(x,i,j,...,drop=TRUE) { if(missing(drop)) drop <- TRUE return(.leftBracket(x@widget, x@toolkit,i,j,...,drop=drop)) }) ##' generic for implementing [ at toolkit level setGeneric(".leftBracket",function(x, toolkit, i,j, ..., drop=TRUE) standardGeneric(".leftBracket")) ################ [<- ################################## ##' base [<- method for guiWidget. ##' ##' For selction widgets this method allows the possible selected values to be set ##' @param x guiWidget selection widget instance ##' @param i index of vector or row, if appropriate ##' @param j index of coumn, if appropriate ##' @param ... mostly ignored, but some toolkits may implement hidden arguments ##' @param value new value setReplaceMethod("[",signature(x="guiWidget"), function(x,i,j,...,value) { toolkit = x@toolkit if(missing(i) && missing(j)) .leftBracket(x@widget, toolkit,...) <- value else if(missing(j)) .leftBracket(x@widget, toolkit,i,...) <- value else .leftBracket(x@widget, toolkit,i,j,...) <- value return(x) }) ##' generic for .leftBracket<- to implement [<- at toolkit level setGeneric(".leftBracket<-",function(x, toolkit, i,j, ..., value) standardGeneric(".leftBracket<-")) ################## visible ################################ ##' Generic to check visibility of widget ##' ##' @param obj guiWidget instance ##' @param set logical. Should one set the value. One should use ##' \code{visible<-} in most all cases, but for \code{gbasicdialog} ##' this is necessary ##' @return logical indicating if object is visible (shown) ##' @export setGeneric("visible",function(obj, set=NULL, ...) standardGeneric("visible")) ##' visible method for widgets setMethod("visible",signature(obj="guiWidget"), function(obj, set=NULL, ...) { toolkit = obj@toolkit .visible(obj@widget,toolkit, set=set, ...) }) ##' dispatch with toolkit ##' @alias visible setGeneric(".visible",function(obj, toolkit, set=NULL, ...) standardGeneric(".visible")) ############### visible<- ################################### ##' Generic method to adjust visibility of object ##' ##' A widget is visible if it is drawn (shown). This method is used to toggle that state. ##' @param obj guiWidget instance ##' @param ... ignored ##' @param value logical. Should object be visible or hidden ##' @note Many widgets override this method. If that is the case and ##' you wish to hide the widget, then place in a box container. ##' @return Called for side effect ##' @export setGeneric("visible<-",function(obj, ..., value) standardGeneric("visible<-")) ##' visible<- method for widgets setReplaceMethod("visible",signature(obj="guiWidget"), function(obj, ..., value) { toolkit = obj@toolkit .visible(obj@widget, toolkit, ...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias visible<- setGeneric(".visible<-",function(obj, toolkit,...,value) standardGeneric(".visible<-")) ############### enabled ################################### ##' Generic to check if widget is sensitive to user input ##' ##' @param obj guiWiget object ##' @param ... ignored ##' @return logical indicating if widget is sensitive to user input ##' @export setGeneric("enabled",function(obj, ...) standardGeneric("enabled")) ##' Method to check if widget is sensitive to user input setMethod("enabled",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .enabled(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias enabled setGeneric(".enabled",function(obj, toolkit,...) standardGeneric(".enabled")) ################ enabled<- ################################## ## Generic to set whether widget is sensitive to user input setGeneric("enabled<-",function(obj, ..., value) standardGeneric("enabled<-")) ## method to adjust whether widget is sensitive to user input setReplaceMethod("enabled",signature(obj="guiWidget"), function(obj, ..., value) { toolkit = obj@toolkit .enabled(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias enabled<- setGeneric(".enabled<-",function(obj, toolkit,...,value) standardGeneric(".enabled<-")) ############### editable ################################### ##' Generic to check if widget can be edited setGeneric("editable",function(obj, ...) standardGeneric("editable")) ##' Method to check if widget can be edited setMethod("editable",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .editable(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias editable setGeneric(".editable",function(obj, toolkit,...) standardGeneric(".editable")) ################ editable<- ################################## ## Generic to set whether widget can be edited setGeneric("editable<-",function(obj, ..., value) standardGeneric("editable<-")) ## method to adjust whether widget can be edited setReplaceMethod("editable",signature(obj="guiWidget"), function(obj, ..., value) { toolkit = obj@toolkit .editable(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias editable<- setGeneric(".editable<-",function(obj, toolkit,...,value) standardGeneric(".editable<-")) ############## size #################################### ##' Generic for size method setGeneric("size",function(obj, ...) standardGeneric("size")) ##' Method to return preferred size of widget setMethod("size",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .size(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias size setGeneric(".size",function(obj, toolkit,...) standardGeneric(".size")) ############### sizes<- ################################### ## Generic for method to adjust size of widget setGeneric("size<-",function(obj, ..., value) standardGeneric("size<-")) ##' Method to adjust size of widget ##' ##' setMethod("size<-",signature(obj="guiWidget"), function(obj, ..., value) { toolkit = obj@toolkit .size(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias size<- setGeneric(".size<-",function(obj, toolkit,...,value) standardGeneric(".size<-")) ################# font ################################# ##' Generic to get the font information setGeneric("font",function(obj, ...) standardGeneric("font")) ## base method for font generic setMethod("font",signature(obj="guiWidget"), function(obj, ...) { toolkit <- obj@toolkit .font(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias font setGeneric(".font",function(obj,toolkit,...) standardGeneric(".font")) ################# font<- ################################# ##' Generic to set font properties of widget setGeneric("font<-",function(obj, ..., value) standardGeneric("font<-")) ##' base method for setting font properties of a widget setMethod("font<-",signature(obj="guiWidget"), function(obj, ..., value) { toolkit <- obj@toolkit .font(obj@widget, toolkit,...) <- value ## DEPRECATED.fixFontMessUp(value) return(obj) }) ##' dispatch with toolkit ##' @alias font<- setGeneric(".font<-",function(obj, toolkit,...,value) standardGeneric(".font<-")) ############## tag #################################### ##' Generic for retrieving data from an object setGeneric("tag",function(obj,i, drop=TRUE, ...) standardGeneric("tag")) ## base method for retrieving data from a widget setMethod("tag",signature(obj="guiWidget"), function(obj,i,drop=TRUE, ...) { toolkit = obj@toolkit .tag(obj@widget, toolkit,i, drop=drop,...) }) ##' dispatch with toolkit ##' @alias tag setGeneric(".tag",function(obj, toolkit,i, drop=TRUE,...) standardGeneric(".tag")) ################ tag<- ################################## ##' Generic to set arbitrary data in an object setGeneric("tag<-",function(obj, i, replace=TRUE, ..., value) standardGeneric("tag<-")) ##' base method for assigning data to an object setMethod("tag<-",signature(obj="guiWidget"), function(obj, i, replace=TRUE, ..., value) { toolkit <- obj@toolkit .tag(obj@widget, toolkit,i, replace, ...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias tag<- setGeneric(".tag<-",function(obj, toolkit,i, replace=TRUE,...,value) standardGeneric(".tag<-")) ################ id ################################## ##' Generic to retrieve id of object setGeneric("id",function(obj, ...) standardGeneric("id")) ##' Base method to retrieve id from an object setMethod("id",signature(obj="guiWidget"), function(obj, ...) { toolkit <- obj@toolkit .id(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias id setGeneric(".id",function(obj, toolkit,...) standardGeneric(".id")) ################ id<- ################################## ##' Generic to set id for an object setGeneric("id<-",function(obj, ..., value) standardGeneric("id<-")) ##' base method to set id for an object setMethod("id<-",signature(obj="guiWidget"), function(obj, ..., value) { toolkit = obj@toolkit .id(obj@widget,toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias id<- setGeneric(".id<-",function(obj, toolkit,...,value) standardGeneric(".id<-")) ############## isExtant #################################### ##' generic to check if a widget still exists setGeneric("isExtant",function(obj, ...) standardGeneric("isExtant")) ##' base method to check if a widget still exists setMethod("isExtant",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .isExtant(obj@widget,toolkit, ...) }) ##' dispatch with toolkit ##' @alias isExtant setGeneric(".isExtant",function(obj, toolkit, ...) standardGeneric(".isExtant")) ################## toolkitProvidesWidget ################################ ##' function to check if a toolkit provides a widget ##' ##' @export ##' @param widgetname Character. Name of widget ##' @param toolkit the toolkit to check ##' @returns a logical indicating if the widget is implemented in the toolkit toolkitProvidesWidget <- function( widgetname, toolkit=guiToolkit()){ .toolkitProvidesWidget (toolkit, widgetname) } ##' generic for toolkit dispatch ##' @alias toolkitProvidesWidget setGeneric( '.toolkitProvidesWidget' , function(toolkit, widgetname) standardGeneric( '.toolkitProvidesWidget' )) ##' implementation for ANY toolkit ##' @alias toolkitProvidesWidget setMethod(".toolkitProvidesWidget", signature(toolkit="ANY"), function(toolkit, widgetname) { notThere <- list(guiWidgetsToolkitQt=c("ggraphics","ggraphicsnotebook"), guiWidgestToolkitRGtk2=c("gsvg", "ghtml"), guiWidgetsrToolkitJava=c("gsvg", "ghtml", "ggraphics", "ggraphicsnotebook"), guiWidgetsToolkittcltk=c("gsvg", "ghtml", "ggraphics", "ggraphicsnotebook", "gdfnotebook") ) notThere <- notThere[[class(toolkit)]] return(!widgetname %in% notThere) }) ################################################## ## Usual R methods made into methods for dispatch ################### update ############################### ##' generic for update setGeneric("update") ##' base method for update to dispatch on guiWidget instances setMethod("update",signature(object="guiWidget"), function(object, ...) { .update(object@widget, object@toolkit, ...) }) ##' generic for toolkit dispatch ##' @alias update setGeneric(".update",function(object, toolkit, ...) standardGeneric(".update")) ##' Base method to find length of guiWidget instances setMethod("length",signature(x="guiWidget"), function(x) { .length(x@widget, x@toolkit) }) ##' generic for toolkit dispatch ##' @alias length setGeneric(".length",function(x, toolkit) standardGeneric(".length")) ############## dim #################################### ##' base method to find dim(ension) of guiWidget instances setMethod("dim",signature(x="guiWidget"), function(x) { .dim(x@widget, x@toolkit) }) ##' generic for toolkit dispatch ##' @alias dim setGeneric(".dim",function(x, toolkit) standardGeneric(".dim")) ##' base method to find dimnames attribute of guiWidget instance #setGeneric("dimnames") setMethod("dimnames",signature(x="guiWidget"), function(x) { .dimnames(x@widget, x@toolkit) }) ##' generic for toolkit dispatch ##' @alias dimnames setGeneric(".dimnames",function(x, toolkit) standardGeneric(".dimnames")) ##' base method to set dimnames for guiWidget instance #setGeneric("dimnames<-") setReplaceMethod("dimnames",signature(x="guiWidget"), function(x,value) { .dimnames(x@widget, x@toolkit) <- value return(x) }) ##' generic for toolkit dispatch ##' @alias dimnames<- setGeneric(".dimnames<-",function(x, toolkit, value) { standardGeneric(".dimnames<-") }) ## names ## as of 2.5.0 this became primiive if(as.numeric(R.Version()$major) <= 2 & as.numeric(R.Version()$minor) <= 4.1) { setGeneric("names") setGeneric("names<-") } ##' Base method for getting names of guiWidget instances setMethod("names",signature(x="guiWidget"), function(x) { .names(x@widget, x@toolkit) }) ##' generic for toolkit dispatch ##' @alias names setGeneric(".names",function(x, toolkit) standardGeneric(".names")) ##' base method to set names of guiWidget instance setReplaceMethod("names",signature(x="guiWidget"), function(x,value) { .names(x@widget, x@toolkit) <- value return(x) }) ##' generic for toolkit dispatch ##' @alias names<- setGeneric(".names<-",function(x, toolkit, value) { standardGeneric(".names<-") }) ################################################## ## Work with underlying toolkit objects ################################################## ##' Generic for method to return toolkit widget from guiWidget instance setGeneric("getToolkitWidget",function(obj) standardGeneric("getToolkitWidget")) ##' base method to return toolkit widget from guiWidget instance setMethod("getToolkitWidget",signature(obj="guiWidget"), function(obj) { .getToolkitWidget(obj@widget, obj@toolkit) }) ##' generic for toolkit dispatch ##' @alias getToolkitWidget setGeneric(".getToolkitWidget",function(obj, toolkit) standardGeneric(".getToolkitWidget")) ################## access via $ and [[ ############################# ##' Invoke a method on the underlying toolkit object ##' ##' @param x guiwidget ##' @param meth_name name of method ##' @return function that one can call, as in \code{x$method(a=1)} ##' @export "$.guiWidget" <- function(x, meth_name) .callToolkitMethod(x@widget, x@toolkit, meth_name) setGeneric(".callToolkitMethod",function(x, toolkit, meth_name) standardGeneric(".callToolkitMethod")) ##' Get an underlying property of the toolkit object ##' @param x guiWidget ##' @param ... first argument has property ##' @return value ##' @export ##' "[[.guiWidget" <- function(x, ...) { property <- list(...)[[1]] .getToolkitProperty(x@widget, toolkit=x@toolkit, property=property) } setGeneric(".getToolkitProperty",function(x, toolkit, property) standardGeneric(".getToolkitProperty")) ##' Set underlying toolkit property ##' @param x guiWidget ##' @param i property to set ##' @param j ignored ##' @param value new value of property ##' @export "[[<-.guiWidget" <- function(x, i, j, value) { .setToolkitProperty(x@widget, toolkit=x@toolkit, property=i, value=value) x } setGeneric(".setToolkitProperty",function(x, toolkit, property, value) standardGeneric(".setToolkitProperty")) gWidgets/R/gcommandline.R0000644000176000001440000002651512377441377015070 0ustar ripleyusers##' @include guiComponents.R ## A widget to provide a simple command line ################################################## ##' Class for a commandline widget setClass("gCommandline", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor of widget for use as a command line ##' ##' Basically a giant hack ##' @exports ##' @param command Initial command to evaluation ##' @param assignto Character or NULL. assign value to this name if non-NULL ##' @param useGUI use the GUI ##' @param useConsole use the console ##' @param prompt what prompt to use ##' @param width width in pixels ##' @param height height in pixels ##' @param container parent container ##' @param ... passed to containers \code{add} method ##' @param toolkit toolkit ##' @return an object of class \code{gCommandline} with methods: ##' ##' \enumerate{ ##' ##' \item{svalue<-} Character. An expression to evaluate. If it has a names attribute this is used for assignment ##' ##' \item{[} Lists history ##' ##' } gcommandline =function( command = "", assignto = NULL, useGUI = TRUE, useConsole = FALSE, prompt = getOption("prompt"), width = 500, height = 0.6 * width, container = NULL, ... , toolkit=guiToolkit()){ widget = .gcommandline (toolkit, command=command, assignto=assignto, useGUI = useGUI, useConsole=useConsole, prompt=prompt, width=width, height=height, container=container, ... ) obj = new( 'guiComponent',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gcommandline setGeneric( '.gcommandline' , function(toolkit, command = "", assignto = NULL, useGUI = TRUE, useConsole = FALSE, prompt = getOption("prompt"), width = 500, height = 0.6 * width, container = NULL, ... ) standardGeneric( '.gcommandline' )) ##' gcommandline implementation for any toolkit setClass("gCommandlineANY", representation=representation("gComponentANY", commandBox="guiWidgetOrNULL", outputBox="guiWidgetOrNULL", histList="guiWidgetOrNULL", useGUI = "logical", useConsole = "logical" ), contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) ##' gcommandline constructor for ANY toolkit ##' @alias gcommandline setMethod(".gcommandline", signature(toolkit="ANY"), function(toolkit, command = "", assignto=NULL, useGUI = TRUE, useConsole = FALSE, prompt = getOption("prompt"), width = 500, height = 0.6 * width, container = NULL, ...) { force(toolkit) .history = character() ## adjust command if need be if(nchar(command) > 0 && !is.null(assignto)) command = addAssignto(command, assignto) if(is(container,"logical") && container) container = gwindow("gCommandLIne") ## if(useGUI == TRUE) { pg <- gpanedgroup(container=container, horizontal=FALSE, expand=TRUE) g <- ggroup(horizontal=FALSE, expand=FALSE, container=pg) bg <- ggroup(container=g, horizontal=TRUE) addSpring(bg) history <- gcheckbox("history", use.togglebutton=TRUE, container=bg) clear <- gbutton("clear", container=bg) evalCmd <- gbutton("evaluate", container=bg) commandBox <- gtext("## Type commands here:\n", container=g, expand=TRUE) size(commandBox) <- c(width, floor(height/3)) outputBox <- gtext("", container=pg, expand=TRUE, fill="both") svalue(pg) <- 0.33 ## History histWindow <- gwindow("History", parent=container, visible=FALSE) addHandlerUnrealize(histWindow, handler=function(h,...) { showHistory(FALSE) FALSE # don't close just hide }) histg <- ggroup(horizontal=FALSE, container=histWindow) glabel("History of recent commands", container=histg) histList <- gtable(data.frame(commands=character(0), stringsAsFactors=FALSE), container=histg, expand=TRUE) histbg <- ggroup(container=histg) addSpring(histbg) gbutton("cancel", container=histbg, handler=function(h,...) { svalue(history) <- FALSE visible(histWindow) <- FALSE # for tcltk focus(commandBox) <- TRUE }) showHistory <- function(bool) { visible(histWindow) <- bool } addHandlerDoubleclick(histList, handler=function(h, ...) { svalue(commandBox) <- svalue(h$obj) focus(commandBox) <- TRUE }) ## handlers addHandlerChanged(history, handler=function(h, ...) { showHistory(svalue(h$obj)) }) ## clear addHandlerChanged(clear, handler=function(h,...) { svalue(commandBox) <- "" focus(commandBox) <- TRUE }) ## evaluate evaluateCommand <- function(...) { cmd <- svalue(commandBox) ## update history list tmp <- histList[,, drop=TRUE] tmp <- c(cmd, tmp) histList[] <- data.frame(commands=tmp, stringsAsFactors=FALSE) ## evaluate command, update outputbox out <- evalChunkReturnOutput(cmd) if(!out$error) { insert(outputBox, out$output) } else { ## an errow, now what insert(outputBox, out$output, font.attr=c(color="red")) } ## clearm move focus to commandBox dispose(commandBox) focus(commandBox) <- TRUE } addHandlerChanged(evalCmd, handler=evaluateCommand) obj = new("gCommandlineANY", block=pg, widget = pg, toolkit=toolkit, ID=getNewID(), commandBox=commandBox, outputBox=outputBox, histList=histList, useGUI = useGUI, useConsole = useConsole ) ## initialize history tag(obj,"history") <- c() } else { obj = new("gCommandlineANY", block=container, widget = container, toolkit=toolkit, ID=getNewID(), commandBox = container, outputBox = container, useGUI = useGUI, useConsole = useConsole ) } if(nchar(command) > 0 ) svalue(obj) <- command return(obj) }) ##' return all previous, or just the index most recent setMethod(".svalue", signature(toolkit="ANY",obj="gCommandlineANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { theArgs = list(...); histList <- obj@histList commandHistory <- histList[,1,drop=TRUE] if(length(commandHistory) == 0) return(c()) if(is.null(index)) { return(commandHistory) } else { n = length(commandHistory) m = max(1, n - index + 1) return(rev(commandHistory[m:n])) } }) ## evaluate command, store in history, swqp out widgets setReplaceMethod(".svalue", signature(toolkit="ANY",obj="gCommandlineANY"), function(obj, toolkit, index=NULL, ..., value) { ## get commane command = value; assignto = names(value) if(!is.null(assignto)) { command = addAssignto(command, assignto) } if(obj@useGUI) svalue(obj@commandBox,font.attr = "monospace") <- command ## add to history tag(obj, "history", replace=FALSE) <- command retVal = evalChunkReturnOutput(command) if(obj@useGUI) add(obj@outputBox, retVal$output) if(obj@useConsole) { cat(retVal$output) } return(obj) }) ## history function setMethod("[", signature(x="gCommandlineANY"), function(x, i, j, ..., drop=TRUE) { .leftBracket(x, x@toolkit, i, j, ..., drop=drop) }) setMethod(".leftBracket", signature(toolkit="ANY",x="gCommandlineANY"), function(x, toolkit, i, j, ..., drop=TRUE) { histList <- x@histList commandHistory <- histList[,1,drop=TRUE] if(missing(i)) return(commandHistory) else commandHistory(i) }) ################################################## ## Helpers ## taken from Sweave ## takes a chunk, interweaves command and output evalChunkReturnOutput = function(chunk, prompt = getOption("prompt")) { output = "" addToOutput = function(...) output <<- paste(output,..., sep=" ", collapse="\n") chunkexps <- try(parse(text=chunk), silent=TRUE) if(inherits(chunkexps,"try-error")) { addToOutput(chunkexps) cat("Houston, we have a problem with:\n",chunkexps,"\n") return(list(output=output, error=TRUE)) } if(length(chunkexps) == 0) return(list(output=output, error=FALSE)) for(nce in 1:length(chunkexps)) { ce <- chunkexps[[nce]] dce <- deparse(ce, width.cutoff=0.75*getOption("width")) command = paste(prompt, paste(dce,collapse=paste("\n", getOption("continue"), sep="")), sep="", collapse="" ) addToOutput(command,"\n") ## is there output? tmpcon <- file() sink(file=tmpcon) err <- RweaveEvalWithOpt(ce, list(eval=TRUE,print=FALSE,term=TRUE,visible=FALSE)) cat("\n") # make sure final line is complete sink() theOutput <- readLines(tmpcon) close(tmpcon) ## delete empty output if(length(theOutput)==1 & theOutput[1]=="") theOutput <- NULL if(inherits(err, "try-error")) { addToOutput(err,"\n") } else { if(!is.null(theOutput)) { addToOutput(paste(theOutput,sep="",collapse="\n")) } } } return(list(output = output, error=FALSE)) } ### working functions ## parse command(s) and make assingment on last one. addAssignto = function(command,assignto) { assignto = make.names(assignto) tmp = unlist(strsplit(command, ";")) if(length(tmp)>1) { command = paste(tmp[-length(tmp)], Paste(assignto,"<-",tmp[length(tmp)]), collapse=";", sep=";") } else { command = Paste(assignto,"<-", command) } return(command) } gWidgets/R/gedit.R0000644000176000001440000000473211637173235013515 0ustar ripleyusers##' @include guiComponents.R ##' single line text edit class setClass("gEdit", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' Single line text edit constructor ##' ##' @exportsg If not text give, and an initial message given, then this message is displayed until the widget receives the focus ##' @param text initial text ##' @param width number of characters ##' @param coerce.with A function or name of function to coerce value with before returning by \code{svalue} ##' @param initial.msg If not text give, and an initial message given, then this message is displayed until the widget receives the focus ##' @param handler Change handler. Called when return key is hit ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to \code{add} method of parent ##' @param toolkit toolkit ##' @return An object of class \code{gEdit}. This has sub-classed methods: ##' ##' \enumerate{ ##' ##' \item \code{} ##' ##' \item \code{svalue} to retrieve the text ##' ##' \item \code{svalue<-} to set the text ##' ##' \item \code{[} to get the autocomplete values ##' ##' \item \code{[<-} Character. To set autocomplete values ##' ##' \item \code{visible<-} to specify a character to display instead of text (for passwords) ##' ##' } ##' ##' The default handler call is when the user activates the entry, ##' typically by pressing the enter key. ##' ##' The \code{addhandlerBlur} ##' method is called when the widget loses focuses. ##' ##' The \code{addHandlerKeystroke} method adds a handler called after ##' each keystroke. If possible, the first argument has a component ##' \code{key} passing back the last value. ##' ##' gedit <- function( text = "", width = 25, coerce.with = NULL, initial.msg="", handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gedit(toolkit, text=text, width=width, coerce.with=coerce.with, initial.msg=initial.msg, handler=handler, action=action, container=container ,... ) obj <- new( 'guiComponent',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gedit setGeneric( '.gedit' , function(toolkit, text = "", width = 25, coerce.with = NULL, initial.msg=initial.msg, handler = NULL,action = NULL, container = NULL, ... ) standardGeneric( '.gedit' )) gWidgets/R/glayout.R0000644000176000001440000000303711613562033014072 0ustar ripleyusers##' @include guiContainer.R ##' Class for a gridded-layout container setClass("gLayout", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' Constructor for grid layout container ##' ##' @export glayout <- function( homogeneous = FALSE, spacing = 10, container = NULL, ... , toolkit=guiToolkit()){ widget <- .glayout (toolkit, homogeneous=homogeneous, spacing=spacing, container=container ,... ) obj <- new( 'gLayout',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias glayout setGeneric( '.glayout' , function(toolkit, homogeneous = FALSE, spacing = 10, container = NULL, ... ) standardGeneric( '.glayout' )) ##' pass back item, list or matrix of items depending on dimension setMethod("[", signature(x="gLayout"), function(x,i,j,...,drop=TRUE) { if(missing(drop)) drop <- TRUE if(missing(i)) i <- seq_len(dim(x)[1]) if(missing(j)) j <- seq_len(dim(x)[2]) if(length(i) == 1 && length(j) == 1) return(.leftBracket(x@widget, x@toolkit,i,j,...,drop=drop)) ## a matrix or list out <- sapply(j, function(col) lapply(i, function(row) x[row, col])) if(is.matrix(out)) return(out[,,drop=drop]) else return(out) }) gWidgets/R/gspinbutton.R0000644000176000001440000000332511613563002014757 0ustar ripleyusers##' @include guiComponent.R ##' ##' ##' ##' RangeSelector Class setClass("guiComponentRangeSelector", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ## svalue, svalue<- [, [<- ##' spinbutton class setClass("gSpinbutton", contains="guiComponentRangeSelector", prototype=prototype(new("guiComponentRangeSelector")) ) ##' Spinbutton constructor ##' ##' @export gspinbutton =function( from = 0, to = 10, by = 1, length.out = NULL, along.with=NULL, value = from, digits = 0, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ ## mostly from seq.default if (!missing(along.with)) { length.out <- length(along.with) } else if(!missing(length.out)) { len <- length(length.out) if (!len) stop("argument 'length.out' must be of length 1") if (len > 1L) { warning("first element used of 'length.out' argument") length.out <- length.out[1L] } length.out <- ceiling(length.out) } if(!is.null(length.out)) { ## set up by to be for length,out by <- (to - from)/(length.out[1] - 1) } widget <- .gspinbutton (toolkit, from=from, to=to, by=by, value=value, digits=digits, handler=handler, action=action, container=container ,... ) obj <- new( 'gSpinbutton',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gspinbutton setGeneric( '.gspinbutton' , function(toolkit, from = 0, to = 10, by = 1, value = from, digits = 0, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gspinbutton' )) gWidgets/R/gtext.R0000644000176000001440000000412311436263646013551 0ustar ripleyusers##' @include guiComponents.R ##' multi-line text edit class setClass("gText", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' Multiline text edit constructor ##' ##' @exports gtext <- function( text = NULL, width = NULL, height = 300, font.attr = NULL, wrap = TRUE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gtext(toolkit, text=text, width=width, height=height, font.attr=font.attr, wrap=wrap, handler=handler, action=action, container=container ,... ) obj <- new( 'gText',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gtext setGeneric( '.gtext' , function(toolkit, text = NULL, width = NULL, height = 300, font.attr = NULL, wrap = TRUE, handler = NULL, action = NULL, container = NULL,... ) standardGeneric( '.gtext' )) ################### methods ############################### ################### insert ############################### ##' generic to insert text into gtext widget setGeneric("insert",function(obj,value, where = c("end","beginning","at.cursor"), font.attr=NULL, do.newline=TRUE, ...) standardGeneric("insert")) ##' insert text method setMethod("insert",signature(obj="gText"), function(obj, value, where = c("end","beginning","at.cursor"), font.attr = NULL, do.newline = TRUE, ...) { toolkit = obj@toolkit where = match.arg(where) .insert(obj@widget, toolkit, value, where, font.attr,do.newline,...) }) ##' dispatch with toolkit ##' @alias insert setGeneric(".insert",function(obj, toolkit,value, where=c("end","beginning","at.cursor"), font.attr=NULL, do.newline=TRUE,...) standardGeneric(".insert")) gWidgets/R/gwindow.R0000644000176000001440000000256711511424555014076 0ustar ripleyusers##' @include guiContainer.R ##' Class for top level windows setClass("gWindow", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' constructor for top-level window ##' ##' @export gwindow <- function(title="Window" , visible=TRUE, name=title, width = NULL, height = NULL, parent = NULL, handler = NULL, action = NULL, ..., toolkit=guiToolkit() ) { theArgs <- list(...) if(!is.null(theArgs$location)) { parent <- theArgs$location cat(gettext("location argument is renamed to 'parent'\n")) } ## THe visible=TRUE default is not the best. I'd change it if I could go back in time, but ## c'est la vie. Anyways, for those that it really bugs there is this check if(!is.null(getOption("gWidgets:gwindow-default-visible-is-false"))) visible <- FALSE win <- .gwindow(toolkit,title, visible,width, height, parent, handler, action, ...) obj <- new("gWindow",widget=win,toolkit=toolkit) return(obj) } ##' define a toolkit constructor, dispatch on toolkit ##' @alias gwindow setGeneric(".gwindow",function(toolkit, title, visible, width, height, parent, handler, action,...) standardGeneric(".gwindow")) ## methods ## add ## svalue: title property ## size, size<- ## visible, visible<- ## update: recompute window size gWidgets/R/guiComponent.R0000644000176000001440000000631111605102246015050 0ustar ripleyusers##' @include guiWidget.R ##' ##' ##' A widget subclass for basic components setClass("guiComponent", contains=c("guiWidget"), prototype=prototype(new("guiWidget")) ) ##' define a subclass setClass("gComponentANY", contains=c("gWidgetANY"), prototype=prototype(new("gWidgetANY")) ) ############### methods ################################### ################ add ################################## ##' method for adding to ghelp, etc setMethod("add",signature(obj="guiComponent"), function(obj, value, ...) { .add(obj@widget, obj@toolkit, value, ...) }) ############### focus ################################### ##' generic to check if a widget has the focus setGeneric("focus",function(obj, ...) standardGeneric("focus")) ##' method to check is a component has the focus setMethod("focus",signature(obj="guiWidget"), function(obj, ...) { toolkit = obj@toolkit .focus(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias focus setGeneric(".focus",function(obj, toolkit,...) standardGeneric(".focus")) ############### focus<- ################################### ##' generic to set focus on a widget setGeneric("focus<-",function(obj, ..., value) standardGeneric("focus<-")) ##' method for setting focus on a component setMethod("focus<-",signature(obj="guiWidget"), function(obj, ..., value) { toolkit <- obj@toolkit .focus(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias focus<- setGeneric(".focus<-",function(obj, toolkit,...,value) standardGeneric(".focus<-")) ############### tooltip<- ################################### ##' generic to set a tooltip for a component setGeneric("tooltip<-",function(obj, ..., value) standardGeneric("tooltip<-")) ##' base method for setting a toolktip setMethod("tooltip<-",signature(obj="guiComponent"), function(obj, ..., value) { toolkit <- obj@toolkit .tooltip(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias tooltip<- setGeneric(".tooltip<-",function(obj, toolkit,...,value) standardGeneric(".tooltip<-")) ############## undo #################################### ##' Generic to implement undo feature in widgets setGeneric("undo",function(obj, ...) standardGeneric("undo")) ##' base method for undo setMethod("undo",signature(obj="guiComponent"), function(obj, ...) { toolkit = obj@toolkit .undo(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias undo setGeneric(".undo",function(obj,toolkit,...) standardGeneric(".undo")) ############## redo #################################### ##' Generic to implement redo feature in widgets setGeneric("redo",function(obj, ...) standardGeneric("redo")) ##' Base method for redo setMethod("redo",signature(obj="guiComponent"), function(obj, ...) { toolkit = obj@toolkit .redo(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias redot setGeneric(".redo",function(obj,toolkit,...) standardGeneric(".redo")) gWidgets/R/gnotebook.R0000644000176000001440000000175411436261463014407 0ustar ripleyusers##' @include guiContainer.R ##' Class for tabbed notebook container setClass("gNotebook", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' Constructor for a tabbed notebook container ##' ##' @export gnotebook <- function( tab.pos = 3, closebuttons = FALSE, dontCloseThese = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gnotebook (toolkit, tab.pos=tab.pos, closebuttons=closebuttons, dontCloseThese=dontCloseThese, container=container ,... ) obj <- new( 'gNotebook', widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gnotebook setGeneric( '.gnotebook' , function(toolkit, tab.pos = 3, closebuttons = FALSE, dontCloseThese = NULL, container = NULL, ... ) standardGeneric( '.gnotebook' )) gWidgets/R/gexpandgroup.R0000644000176000001440000000333711511510243015105 0ustar ripleyusers##' @include gframe.R ##' Class for a box container with disclosure trigger setClass("gExpandGroup", contains="gFrame", prototype=prototype(new("gFrame")) ) ##' Constructor of box container widget with disclosure trigger and label ##' ##' @export ##' @param text Label text ##' @param markup logical. Does text have markup. (not too many) ##' @param horizontal horizontal (\code{TRUE}) or vertical packing. ##' @param handler handler called when toggled ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to parent's \code{add} method ##' @param toolkit toolkit ##' @return An object of class \code{gExpandgroup}. This (basically) ##' inherits from \code{gFrame} its methods and overrides: ##' ##' \enumerate{ ##' ##' \item \code{visible<-} Logical. To specify if widget is open (\code{TRUE}) or closed. ##' ##' } ##' ##' gexpandgroup <- function( text = "", markup = FALSE, horizontal=TRUE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gexpandgroup (toolkit, text=text, markup=markup, horizontal=horizontal, handler=handler, action=action, container=container ,... ) obj <- new( 'gExpandGroup',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gexpandgroup setGeneric( '.gexpandgroup' , function(toolkit, text = "", markup = FALSE,horizontal=TRUE, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gexpandgroup' )) gWidgets/R/gpanedgroup.R0000644000176000001440000000154211436261730014723 0ustar ripleyusers##' @include guiContainer.R ##' Class for a two-paned container setClass("gPanedGroup", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' constructor for a two-paned container ##' ##' @export gpanedgroup <- function( widget1=NULL, widget2=NULL, horizontal = TRUE, container = NULL , ..., toolkit=guiToolkit()){ widget <- .gpanedgroup (toolkit, widget1, widget2, horizontal=horizontal, container=container, ... ) obj <- new( 'gPanedGroup',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gpanedgroup setGeneric( '.gpanedgroup' , function(toolkit, widget1, widget2, horizontal = TRUE, container = NULL, ... ) standardGeneric( '.gpanedgroup' )) gWidgets/R/gimage.R0000644000176000001440000000174011436253735013647 0ustar ripleyusers##' @include guiComponents.R ##' Class for widget to embed a graphic image setClass("gImage", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' A widget for displaying an image ##' ##' @exports gimage <- function( filename = "", dirname = "", size = "", handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gimage (toolkit, filename=filename, dirname=dirname, size=size, handler=handler, action=action, container=container ,... ) obj <- new( 'gImage',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gimage setGeneric( '.gimage' , function(toolkit, filename = "", dirname = "", size = "", handler = NULL,action = NULL, container = NULL, ... ) standardGeneric( '.gimage' )) gWidgets/R/gstatusbar.R0000644000176000001440000000137311436254207014572 0ustar ripleyusers##' @include guiComponents.R ##' Class for adding a status bar to main window setClass("gStatusbar", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor to add a status bar to main window ##' ##' @exports gstatusbar <- function( text = "", container = NULL, ... , toolkit=guiToolkit()){ widget <- .gstatusbar (toolkit, text=text, container=container ,... ) obj <- new( 'gStatusbar',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gstatusbar setGeneric( '.gstatusbar' , function(toolkit, text = "", container = NULL, ... ) standardGeneric( '.gstatusbar' )) gWidgets/R/gformlayout.R0000644000176000001440000001660611515632214014764 0ustar ripleyusers## a way to layout out a form (dialog) using a list, similar to ggenericwidget ## but perhaps better ## idea is taken from extjs www.extjs.com ##' @include guiComponents.R ##' Class for widget to layout form from a specification in a list setClass("gFormLayout", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' A constructor for a widget to layout a form from a specification in a list ##' ##' @export gformlayout <- function( lst, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gformlayout(toolkit, lst=lst, container=container ,... ) obj <- new( 'gFormLayout',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gformlayout setGeneric( '.gformlayout' , function(toolkit, lst, container = NULL, ... ) standardGeneric( '.gformlayout' )) ################################################## ## ANY implementation setClass("gFormLayoutANY", representation = representation("gComponentANY", lst="list"), contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) ############### setMethod(".gformlayout", signature(toolkit="ANY"), function(toolkit, lst, container=NULL, ... ) { ## see docs for description of the list e <- new.env() mainGroup <- ggroup(container = container, ...) .makeForm(lst, mainGroup, e) ## return the container now that it has all the stuff in in. obj = new("gFormLayoutANY", block=mainGroup, widget=mainGroup, ID = getNewID(), toolkit=toolkit, lst = lapply(e, function(i) i)) invisible(obj) }) ### methods setMethod("[", signature(x="gFormLayoutANY"), function(x, i, j, ..., drop=TRUE) { .leftBracket(x, x@toolkit, i, j, ..., drop=drop) }) ## return list containing widgets setMethod(".leftBracket", signature(toolkit="ANY",x = "gFormLayoutANY"), function(x, toolkit, i, j, ..., drop = TRUE) { widgets <- x@lst if(missing(i)) return(widgets) else if(length(i) == 1 && drop == TRUE) return(widgets[[i]]) else return(widgets[i]) }) ## return a list of values setMethod(".svalue", signature(toolkit="ANY",obj="gFormLayoutANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { return(lapply(obj[], svalue)) }) setMethod(".names", signature(toolkit="ANY",x="gFormLayoutANY"), function(x, toolkit) { return(names(x[])) }) ## changes here should be copied into gWidgetsWWW ## helper functions .makeForm <- function(lst, parent, e, ...) { g <- ggroup(container = parent, expand=TRUE,...) ## make a local copy of lst and modify for do.call tmp <- lst; tmp$name <- tmp$type <- tmp$children <- NULL tmp$depends.on <- tmp$depends.FUN <- tmp$depends.signal <- NULL tmp$container <- g; tmp$expand <- TRUE ## treat fieldset differently if(lst$type == "fieldset") { .makeFieldset(lst, g, e, label = lst$label) return() } else { ## make object newObject <- do.call(lst$type, tmp) ## store if a name is given if(!is.null(lst$name)) e[[lst$name]] <- newObject ## do we enable new object if(!is.null(lst$depends.on)) { widget <- e[[lst$depends.on]] if(is.null(lst$depends.signal)) lst$depends.signal <- "addHandlerChanged" do.call(lst$depends.signal,list(obj=widget,handler = function(h,...) { value <- svalue(h$obj) enabled(newObject) <- lst$depends.FUN(value) })) enabled(newObject) <- lst$depends.FUN(svalue(widget)) } } ## show children if there ## this recurses except on "fieldset" if(!is.null(lst$children)) { for(i in 1:length(lst$children)) { l <- lst$children[[i]] if(l$type == "fieldset") { if(lst$type == "gnotebook") .makeFieldset(l, newObject, e, label = l$label) else .makeFieldset(l, newObject, e) } else { if(lst$type == "gnotebook") .makeForm(l, newObject, e, label = l$label) else .makeForm(l, newObject, e) } } } } ## fieldset does not recurse .makeFieldset <- function(lst, parent, e, ...) { ## parent is parent container ## lst is list as above ## outer container if(!is.null(lst$label)) g <- gframe(lst$label, container = parent, ...) else g <- ggroup(container = parent, ...) ## main table tbl <- glayout(container = g) ## do we enable new object if(!is.null(lst$depends.on)) { widget <- e[[lst$depends.on]] if(is.null(lst$depends.signal)) lst$depends.signal <- "addHandlerChanged" do.call(lst$depends.signal, list(obj = widget,handler = function(h,...) { value <- svalue(h$obj) enabled(g) <- lst$depends.FUN(value) })) enabled(g) <- lst$depends.FUN(svalue(widget)) } ## fix label adjust if(is.null(lst$label.pos)) lst$label.pos <- "left" if(lst$label.pos == "top") { label.anchor <- c(-1,0) } else { if(is.null(lst$label.just) || lst$label.just == "left") label.anchor <- c(-1,1) else if(lst$label.just == "center") label.anchor <- c(0,1) else label.anchor <- c(1,1) } if(is.null(lst$columns)) no.columns <- 1 else no.columns <- lst$columns ## add children for(i in 1:length(lst$children)) { l <- lst$children[[i]] ## each child is a list with name, label, type, then arguments ## make new list for do.call tmp <- l; tmp$name <- tmp$label <- tmp$type <- NULL tmp$depends.on <- tmp$depends.FUN <- tmp$depends.signal <- NULL tmp$container <- tbl newWidget <- do.call(l$type, tmp) ## store if(!is.null(l$name)) e[[l$name]] <- newWidget ## do we enable new object if(!is.null(l$depends.on)) { widget <- e[[l$depends.on]] if(is.null(l$depends.signal)) l$depends.signal <- "addHandlerChanged" do.call(l$depends.signal, list(obj = widget, handler = function(h,...) { value <- svalue(h$obj) enabled(newWidget) <- l$depends.FUN(value) })) enabled(newWidget) <- l$depends.FUN(svalue(widget)) } ## add to table col <- 1 + (i - 1) %% no.columns #1, ..., no.columns row <- 1 + (i - 1) %/% no.columns #1, ... newLabel <- glabel(l$label, container = tbl) if(!is.null(lst$label.font)) font(newLabel) <- lst$label.font if(is.null(lst$label.pos) || lst$label.pos == "left") { tbl[row, 2 * (col - 1) + 1, anchor=label.anchor] <- newLabel if(l$type %in% c("gcombobox","gdroplist")) tbl[row, 2 * (col - 1) + 2, anchor=c(-1,1), expand=TRUE] <- newWidget else tbl[row, 2 * (col - 1) + 2, anchor=c(-1,1)] <- newWidget } else { tbl[2 * (row - 1) + 1, col, anchor=label.anchor] <- newLabel if(l$type %in% c("gcombobox","gdroplist")) tbl[2 * (row - 1) + 2, col, anchor=c(-1,1), expand=TRUE] <- newWidget else tbl[2 * (row - 1) + 2, col, anchor=c(-1,1)] <- newWidget } } } gWidgets/R/gframe.R0000644000176000001440000000165011436261131013644 0ustar ripleyusers##' @include ggroup.R ##' Class for framed box container with label setClass("gFrame", contains="gGroup", prototype=prototype(new("gGroup")) ) ##' Constructor for framed box container with label ##' ##' @export gframe <- function( text = "", markup = FALSE, pos = 0, horizontal=TRUE, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gframe (toolkit, text=text, markup=markup, pos=pos, horizontal=horizontal, container=container , ... ) obj <- new( 'gFrame',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gframe setGeneric( '.gframe' , function(toolkit, text = "", markup = FALSE, pos = 0, horizontal=TRUE, container = NULL, ... ) standardGeneric( '.gframe' )) gWidgets/R/aaaGenerics.R0000644000176000001440000000463211436272570014621 0ustar ripleyusers################################################## ### Code to handle toolkits ### A new toolkit should have: ### * a name gWidgetsXXXXX ### * a subclass of guiWidgetsToolkit ### * methods for .functions (.glabel, .svalue, ...) ### * optionally, methods for glabel(obj, ...) dispatching to .glabel(obj,toolkit, ...) ### toolkit code comes *before* others ################################################## ### Components ## gcheckbox ## the constructor ## gradio ## constructor ## gdroplist ## the class ## the constructor ## gcheckboxgroup ## the constructor ## gspinbutton ## the constructor ## gslider ## the constructor ## gedit ## the constructor ## gtext ## the constructor ## gaction ## gmenu ## the constructor ## gtoolbar ## the constructor ## gtable ## the constructor ## gdf ## the constructor ## gdfnotebook ## the constructor ## gtree ## the constructor ## gfile (gfilebrowse in base) ## the constructor ## gcalendar ## the constructor ## ggraphics ## the constructor ## gplotnotebook ## the constructor ## gimage ## the constructor ## gsvg ## the constructor ## gstatusbar ## the constructor ## ghtml function ## gseparator ## the constructor ################################################## ## these should be in gWidgets, based on others no toolkit specific code ## the constructor ## ghelp, ghelpbrowser ## the constructor ## ggenericwidget ## the constructor ## gformlayout ## the constructor ## gvarbrowser ## the constructor ################################################## ### Containers ## define a gWidget constructor ## not a generice ## ggroup ## the constructor ## gframe ## the constructor ## gexpandgroup ## the constructor ## gnotebook ## the constructor ## glayout ## the constructor ## gpanedgroup ## the constructor ## icons ################################################## ## ## Methods ## add ## focus ## focus<- ## tooltip ## font ## font<- ## undo ## redo ## tag ## tag<- ## id ## id<- ## toOlkitprovidesgwidgetsdg ## Does thie toolkit provide the widget ## the constructor ################################################## ## #### ## put into RGtk2 only ## ## S3 class for coercing to gWidget ## as.gWidget <- function(obj,...) UseMethod("as.gWidget") ## as.gWidget.default <- function(obj,...) { ## print(sprintf("No coercion to gWidget available for object of class %s",class(obj))) ## return(obj) ## } gWidgets/R/gsvg.R0000644000176000001440000000366611511455750013370 0ustar ripleyusers##' @include guiComponents.R ##' Class for widget to display SVG data setClass("gSvg", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' construtor for widget to display svg data ##' ##' Reimplemented methods: ##' \enumerate{ ##' \item \code{svalue} returns file name ##' \item \code{svalue<-} set image from file ##' } ##' @exports ##' @param filename name of file to write to ##' @param width width in pixels ##' @param height height in pixels ##' @param handler (if implemented) add handler to be called on mouse click ##' @param action passed to handler ##' @param container parent container ##' @param ... passed to \code{add} method of container ##' @param toolkit toolkit ##' @note A native svg driver is available for Qt, but not tcltk, Gtk. gsvg <- function( filename="", width=480, height=480, handler=NULL, action=NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gsvg (toolkit, filename=filename, width=width, height=height, handler=handler, action=action, container=container ,... ) obj <- new( 'gSvg',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gsvg setGeneric( '.gsvg' , function(toolkit, filename = "", width=480, height=480, handler=NULL, action=NULL, container = NULL, ... ) standardGeneric( '.gsvg' )) ##' gsvg constructor for ANY class (default to label) setMethod(".gsvg", signature(toolkit="ANY"), function(toolkit, filename = "", width=480, height=480, handler=NULL, action=NULL, container = NULL, ...) { cat(gettext("gsvg widget not imlemented")) return(glabel(container=container, ...)) }) gWidgets/R/icons.R0000644000176000001440000001303611555316577013540 0ustar ripleyusers##' @include guiComponent.R ##' ##' Method to add icon to list of stock icons ##' ##' @export addStockIcons = function(iconNames,iconFiles, ..., toolkit = guiToolkit()) { out = .addStockIcons (toolkit, iconNames, iconFiles, ...) return(out) } ##' generic for dispath ##' @alias addStockIcons setGeneric( '.addStockIcons' , function(toolkit, iconNames, iconFiles,... ) standardGeneric( '.addStockIcons' )) ##' return list of available stock icons ##' ##' @export getStockIcons = function( ..., toolkit = guiToolkit()) { out = .getStockIcons (toolkit,...) return(out) } ##' generic for toolkit dispatch ##' @alias getStockIcons setGeneric( '.getStockIcons' , function(toolkit,...) standardGeneric( '.getStockIcons' )) ##' Find a stock icon from the given class ##' ##' @export stockIconFromClass = function(theClass, ..., toolkit = guiToolkit()) { out = .stockIconFromClass (toolkit, theClass, ...) return(out) } ##' generic for dispath ##' @alias stockIconFromClass setGeneric( '.stockIconFromClass' , function(toolkit, theClass,... ) standardGeneric( '.stockIconFromClass' )) ##' Find stock icon from the given object ##' ##' @export stockIconFromObject = function(obj, ..., toolkit = guiToolkit()) { out = .stockIconFromClass (toolkit, obj, ...) return(out) } ##' generic for dispath ##' @alias stockIconFromObject setGeneric( '.stockIconFromObject' , function(toolkit, obj,... ) standardGeneric( '.stockIconFromObject' )) ## returns a list with key the icon name ## and value the filepath ## find the stock icons. This includes those added bia loadGWidgetIcons() gWidgetsIcons = list() assignInNamespace("gWidgetsIcons",gWidgetsIcons,ns="gWidgets") addedStockIcons = list() assignInNamespace("addedStockIcons",addedStockIcons, ns="gWidgets") getgWidgetsIcons = function() { gWidgetsIcons = getFromNamespace("gWidgetsIcons",ns="gWidgets") if(length(gWidgetsIcons) == 0) { path = system.file("images",package="gWidgets") allIcons = list.files(path) ## create a hash with name -> location for(i in allIcons) { filename = sub("\\.xpm$|\\.gif$|\\.jpg$|\\.jpeg$|\\.png$|\\.tiff$","",i) gWidgetsIcons[[filename]] <- system.file("images",i,package="gWidgets") } } assignInNamespace("gWidgetsIcons",gWidgetsIcons,ns="gWidgets") return(gWidgetsIcons) } ## incorporate both these and any additional ones added via addStockIcons setMethod(".getStockIcons", signature(toolkit="ANY"), function(toolkit) { gWidgetsIcons = getgWidgetsIcons() addedStockIcons = getFromNamespace("addedStockIcons",ns="gWidgets") return(c(addedStockIcons ,gWidgetsIcons)) }) setMethod(".addStockIcons", signature(toolkit="ANY"), function(toolkit, iconNames, iconFiles, ...) { stockIcons = getgWidgetsIcons() addedStockIcons = getFromNamespace("addedStockIcons", ns="gWidgets") if(length(iconNames) == length(iconFiles)) { for(i in 1:length(iconNames)) { if(!is.na(match(iconNames[i],names(stockIcons)))) cat("Overriding stock icon",iconNames[i],"\n") addedStockIcons[[iconNames[i]]] <- iconFiles[[i]] } assignInNamespace("addedStockIcons", addedStockIcons, ns="gWidgets") } else { cat("Lengths of names and file don't match\n") } invisible() }) ## name can be a vector ## return NA, if not there getstockiconname = function(name=NULL) { .stockicons = getStockIcons() # cache? if(is.null(name)) return(unlist(.stockicons)) tmpfun = function(names) { sapply(names, function(name) { ## already a stock name? if(name %in% .stockicons) return(name) if(name %in% names(.stockicons)) { return(.stockicons[[name]]) } else { return(NA) } }) } return(tmpfun(name)) } ################################################# ## functions to deal with icons ## class to icon translation -- return stock name ## with prefix ## find the stock icons. This includes those added bia loadGWidgetIcons() setMethod(".stockIconFromClass", signature(toolkit="ANY"), function(toolkit,theClass, ...) { default = "symbol_star" if(is.null(theClass) || is.na(theClass) || length(theClass) == 0 ) return(NA) if(theClass %in% .models) return(getstockiconname("lines")) if(theClass %in% .ts) return(getstockiconname("ts")) if(theClass %in% .functions) return(getstockiconname("function1")) ret = switch(theClass, "complex"="numeric", "character"="character", "date" = "date", "data.frame" = "dataframe", "integer"= "numeric", "factor"="factor", "function"="function1", "list" = "dataframe", "logical" = "logical", "matrix" = "matrix", "numeric"= "numeric", "recordedplot" = "plot", NA) return(getstockiconname(ret)) }) setMethod(".stockIconFromObject", signature(toolkit="ANY"), function(toolkit,obj, ...) { .stockIconFromClass(class(obj)[1]) }) gWidgets/R/gvarbrowser.R0000644000176000001440000000166511436260363014762 0ustar ripleyusers##' @include guiComponents.R ##' Class for a workspace or variable browser setClass("gVarBrowser", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' Constructor for workspace variable browser ##' ##' @export gvarbrowser <- function( handler = NULL, action = "summary", container = NULL ,..., toolkit=guiToolkit()){ widget <- .gvarbrowser (toolkit, handler=handler, action=action, container = container, ... ) obj <- new( 'gVarBrowser',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gvarbrowser setGeneric( '.gvarbrowser' , function(toolkit, handler = NULL, action = "summary", container = NULL,... ) standardGeneric( '.gvarbrowser' )) gWidgets/R/ggroup.R0000644000176000001440000000716211462551320013713 0ustar ripleyusers##' @include guiContainer.R ##' Base class for box containers. Subclasses are gFrame, gExpandGroup setClass("gGroup", contains="guiContainer", prototype=prototype(new("guiContainer")) ) ##' Constructor for horizontal or vertical box container ##' ##' @param horizontal layout children left to right (\code{TRUE}) or top to bottom (\code{FALSE}) ##' @param spacing between widget spacing. (No API to set margin size) ##' @param use.scrollwindow if \code{TRUE} uses scrollbars when ##' requested size for children larger than display size of the widget ##' @param container parent container ##' @param ... ignored ##' @param toolkit underlying toolkit, unusual to specify ##' @export ##' @seealso \code{\link{gframe}}, \code{\link{gexpandgroup}} ggroup <- function( horizontal = TRUE, spacing = 5, use.scrollwindow = FALSE, container = NULL, ... , toolkit=guiToolkit()){ widget <- .ggroup (toolkit, horizontal=horizontal, spacing=spacing, use.scrollwindow = use.scrollwindow, container=container,... ) obj <- new( 'gGroup',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' ##' @alias ggroup setGeneric( '.ggroup' , function(toolkit, horizontal = TRUE, spacing = 5, use.scrollwindow = FALSE, container = NULL, ... ) standardGeneric( '.ggroup' )) ################## Methods ############################### ##' Return spacing between widgets in a box container ##' ##' Main property of a box container is the spacing between widgets ##' @param obj object ##' @param index ignored ##' @param drop ignored ##' @param ... ignored ##' @return integer. between widget spacing in pixes setMethod("svalue",signature(obj="gGroup"), function(obj, index=NULL, drop=NULL, ... ) { .svalue(obj@widget, obj@toolkit, ...,index=index, drop=drop) }) ##' set between widget spacing for box containers ##' ##' @param obj ##' @param index ignormed ##' @param ... ignored ##' @param value integer, spacing values setReplaceMethod("svalue",signature(obj="gGroup"), function(obj, index=NULL, ...,value) { .svalue(obj@widget, obj@toolkit, index=index, ...) <- value return(obj) }) ################## addSpace ################################ ##' addSpace generic for box containers ##' ##' @export setGeneric("addSpace",function(obj,value, ...) standardGeneric("addSpace")) ##' Add space between previous child and next one ##' ##' @param obj object ##' @param value integer, pixel size ##' @param ... ignored ##' @return void setMethod("addSpace",signature(obj="gGroup"), function(obj, value, ...) { toolkit = obj@toolkit .addSpace(obj@widget,toolkit,value,...) }) ##' dispatch with toolkit ##' @alias addSpace setGeneric(".addSpace",function(obj,toolkit,value,...) standardGeneric(".addSpace")) ################################################## ##' addSpring generic setGeneric("addSpring",function(obj,...) standardGeneric("addSpring")) ##' addSpring between children for box containers ##' ##' A spring pushes the two children to the sides (or top and bottom) of the box ##' @param obj object ##' @param ... ignored ##' @return void setMethod("addSpring",signature(obj="gGroup"), function(obj, ...) { toolkit = obj@toolkit .addSpring(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias addSpring setGeneric(".addSpring",function(obj, toolkit,...) standardGeneric(".addSpring")) gWidgets/R/gbutton.R0000644000176000001440000000722511637643562014110 0ustar ripleyusers##' @includes guiComponent.R ##' Button class setClass("gButton", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' Button widget constructor ##' ##' @param text Button text. If text matches a stock icon, that icon is also displayed. ##' @param border Logical. Is button drawn with a border ##' @param handler handler to call when button is invoked ##' @param action passed to handler when called. If a \code{gaction} ##' instance, then the action will define the text and the handler ##' @param container parent container ##' @param ... passed to \code{add} method of container ##' @param toolkit toolkit ##' @export ##' @example ~/pmg/r-forge/gwidgets/pkg/gWidgets/inst/tests/ex-gbutton.R ##' @return An object of class \code{gButton} for which the following methods are overridden: ##' ##' \enumerate{ ##' \item \code{svalue} gets button text ##' ##' \item \code{svalue<-} sets button text ##' } ##' The "change" handler is called when the button is clicked. gbutton =function( text = "", border=TRUE, handler = NULL, action = NULL, container = NULL, ..., toolkit=guiToolkit()){ force(toolkit) # load package text <- paste(as.character(text), collapse="\n") widget = .gbutton (toolkit, text, border, handler, action, container,...) obj <- new( 'gButton',widget=widget,toolkit=toolkit) return(obj) } ##' gbutton generic for toolkit dispatch ##' @alias gbutton ##' @export setGeneric( '.gbutton' , function(toolkit, text = "", border=TRUE, handler = NULL, action = NULL, container = NULL,...) standardGeneric( '.gbutton' )) ################ methods ################################## ##' svalue method for button ##' ##' Main property of a button is the label ##' @param obj object ##' @param index ignored ##' @param drop ignored ##' @return character. String on button ##' @exports setMethod("svalue", signature(obj="gButton"), function(obj, index=NULL, drop=NULL, ... ) { callNextMethod() }) ##' set label in a button ##' ##' @param obj ##' @param index ignored ##' @param ... ignored ##' @param value character. If string matches stock icon name, then an icon will be added to button. ##' @return void ##' @exports setReplaceMethod("svalue", signature(obj="gButton"), function(obj, index=NULL, ...,value) { value <- paste(value, collapse="\n") callNextMethod() }) ################## defaultWidget ################################ ##' Generic to check if a button is the default button setGeneric("defaultWidget",function(obj, ...) standardGeneric("defaultWidget")) ##' base method to check if a button is the default setMethod("defaultWidget",signature(obj="gButton"), function(obj, ...) { toolkit <- obj@toolkit .defaultWidget(obj@widget, toolkit,...) }) ##' dispatch with toolkit ##' @alias defaultWidget setGeneric(".defaultWidget",function(obj, toolkit,...) standardGeneric(".defaultWidget")) ################### defaultWidget<- ############################### ##' generic to set a button as the default one setGeneric("defaultWidget<-",function(obj, ..., value) standardGeneric("defaultWidget<-")) ##' base method to set a button as default setMethod("defaultWidget<-",signature(obj="gButton"), function(obj, ..., value) { toolkit = obj@toolkit .defaultWidget(obj@widget, toolkit,...) <- value return(obj) }) ##' dispatch with toolkit ##' @alias defaultWidget<- setGeneric(".defaultWidget<-",function(obj, toolkit,...,value) standardGeneric(".defaultWidget<-")) gWidgets/R/gaction.R0000644000176000001440000000257111507172522014036 0ustar ripleyusers##' @include guiComponents.R ##' single line text edit class setClass("gAction", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' An action constructor ##' ##' @param label label for action ##' @param tooltip toolktip for actin ##' @param icon icon (stock icon name) for icon ##' @param key.accel keyboard accelerator. If given, parent must be specified. ##' @param handler handler to call when action is invoked ##' @param action values passed to parameterize action ##' @param parent parent window. Needed if keyboard accelerator used. ##' @param ... ##' @param toolkit ##' @export ##' @return a gaction instance gaction <- function( label, tooltip=NULL, icon = NULL, key.accel = NULL, handler = NULL, action = NULL, parent=NULL, ..., toolkit=guiToolkit()) { widget <- .gaction (toolkit, label, tooltip, icon, key.accel, handler, action, parent, ... ) obj <- new( 'gAction',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gaction setGeneric( '.gaction' , function(toolkit, label, tooltip = NULL, icon = NULL, key.accel=NULL, handler = NULL, action = NULL, parent=NULL, ... ) standardGeneric( '.gaction' )) gWidgets/R/guiComponentWithItems.R0000644000176000001440000000034211436071011016701 0ustar ripleyusers##' @include guiComponent.R ##' ##' ##' A widget subclass for components with items setClass("guiComponentWithItems", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ## [, [<- gWidgets/R/gcheckboxgroup.R0000644000176000001440000000463611626237273015437 0ustar ripleyusers##' @include guiComponentWithItems.R ##' checkboxgroup class setClass("gCheckboxGroup", contains="guiComponentWithItems", prototype=prototype(new("guiComponentWithItems")) ) ##' Constructor for checkbox group. A linked group of checkboxes, but not exclusive. ##' ##' @export ##' @param items checkbox labels ##' @param checked logical. Are values checked ##' @param horizontal logical. If true displayed horizontally, else vertically ##' @param use.table logical. If supported, and \code{TRUE} then use a table widget with scrollbars ##' @param handler Handler called when state toggles ##' @param action passed to handler when called ##' @param container parent container ##' @param ... passed to \code{add} method of parent ##' @param toolkit toolkit ##' @example ~/pmg/r-forge/gwidgets/pkg/gWidgets/inst/tests/ ##' @return Returns an object of class \code{gCheckboxGroup} for which the following methods are overridden: ##' % ##' \example{ ##' ##' \item \code{svalue} Return the selected values or an empty ##' character vector. If \code{index=TRUE}, returns indices of ##' selected values. ##' ##' \item \code{svalue<-} Set the selected values one of three ways: ##' by label name, by a logical variable indicating which are selected ##' (if ambigous, logical wins), if \code{index=TRUE} by the indices ##' to select. ##' ##' \item \code{[} returns labels ##' ##' \item \code{[<-} set the label values. Should be able to shorten ##' or lengthen list ##' ##' } gcheckboxgroup <- function( items, checked = FALSE, horizontal = FALSE, use.table=FALSE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ if(missing(items)) items <- character(0) horizontal <- as.logical(horizontal) widget <- .gcheckboxgroup (toolkit, items=items, checked=checked, horizontal=horizontal, use.table=use.table, handler=handler, action=action, container=container, ... ) obj <- new( 'gCheckboxGroup',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gcheckboxgroup ##' @export setGeneric( '.gcheckboxgroup' , function(toolkit, items, checked = FALSE, horizontal = FALSE, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gcheckboxgroup' )) gWidgets/R/ghtml.R0000644000176000001440000000161011436254341013517 0ustar ripleyusers##' @include guiComponents.R ##' Class for display of HTML text setClass("gHtml", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor of widget to display HTML text ##' ##' @export ghtml <- function( x, handler = NULL, action = NULL, container = NULL, ..., toolkit=guiToolkit()) { widget <- .ghtml(toolkit, x, handler = handler, action = action, container = container, ...) obj <- new("gHtml",widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias ghtml setGeneric(".ghtml",function(toolkit, x, handler = NULL, action = NULL, container = NULL, ...) standardGeneric(".ghtml")) gWidgets/R/gdfnotebook.R0000644000176000001440000000175311511507210014703 0ustar ripleyusers##' @include guiComponents.R ##' class to hold a notebook of data frame editors setClass("gDfNotebook", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' A notebook container for many \code{gdf} instances ##' ##' @exports ##' @param items data frame for initial page ##' @param container parent container ##' @param ... passed to \code{add} method of parent container ##' @param toolkit toolkit gdfnotebook <- function( items = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .gdfnotebook (toolkit, items=items, container=container ,... ) obj <- new( 'gDfNotebook',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gdfnotebook setGeneric( '.gdfnotebook' , function(toolkit, items = NULL, container = NULL, ... ) standardGeneric( '.gdfnotebook' )) gWidgets/R/gslider.R0000644000176000001440000000425011613567000014034 0ustar ripleyusers##' @include gspinbutton.R ##' slider class setClass("gSlider", contains="guiComponentRangeSelector", prototype=prototype(new("guiComponentRangeSelector")) ) ##' slider widget constructor ##' ##' @param from If a number of length one then a starting point, in ##' which case to, by are passed to \code{seq}. Otherwise a sequence ##' of values for which sort(unique(from)) will order ##' @param to ending point when from is starting point ##' @param by step size if not specified by \code{from} ##' @param length.out in place of by ##' @param along.with in place of length.out ##' @export gslider <- function( from = 0, to = 100, by = 1, length.out=NULL, along.with=NULL, value = from[1], horizontal = TRUE, handler = NULL, action = NULL, container = NULL, ... , toolkit=guiToolkit()){ ## mostly from seq.default ## Wanted to just call seq.default, but that didn't work with length.out bit if (!missing(along.with)) { length.out <- length(along.with) } else if(!missing(length.out)) { len <- length(length.out) if (!len) stop("argument 'length.out' must be of length 1") if (len > 1L) { warning("first element used of 'length.out' argument") length.out <- length.out[1L] } length.out <- ceiling(length.out) } if(!is.null(length.out)) { ## set up by to be for length,out by <- (to - from)/(length.out[1] - 1) } widget <- .gslider (toolkit, from=from, to=to, by=by, value=value, horizontal=horizontal, handler=handler, action=action, container=container ,... ) obj <- new( 'guiComponent',widget=widget,toolkit=toolkit) return(obj) } ##' generic for toolkit dispatch ##' @alias gslider setGeneric( '.gslider' , function(toolkit, from = 0, to = 100, by = 1, value = from, horizontal = TRUE, handler = NULL, action = NULL, container = NULL, ... ) standardGeneric( '.gslider' )) ##' svalue referst o value of slider ##' ##' @param index if non \code{NULL} and \code{TRUE} and sequence specified at once then index gWidgets/MD50000644000176000001440000003044713652210053012374 0ustar ripleyusers9fbef98603c86cadefaba5af2a8b9a3b *ChangeLog 74a4d0e2abf2da193bb9a40f008cfeb0 *DESCRIPTION e591f971e2945c751bee3512a73d1c17 *NAMESPACE db05dfa9103c9017bedc5030670c6460 *NEWS e71b184cfdbadfe186f595afd3d4ce02 *R/aaaGenerics.R b7836e37079c52f38fb6bcfc7f81cd46 *R/bbbGenericsANY.R df66251e89295bd11a92330ae75b3ae9 *R/common.R b586639fb5b6c1d32b8953b4fdaf8220 *R/dialogs.R 7a904e1aaf6202f9e8cfddf6586acdcc *R/gaction.R 04cf76b628567efbebe6091b840ed433 *R/gbutton.R 9630960db1e097cba9a7c11b0e7f3b20 *R/gcalendar.R 8a83a9e2ef646b4201ea27d8a8aa2c77 *R/gcheckbox.R 128110caf4ac4e7b1f737e449fc0de37 *R/gcheckboxgroup.R 70e71c02a51f696e40c7fbe48d25f60e *R/gcombobox.R 44466642db07e71efdebcb7bf1724ebd *R/gcommandline.R 463c36bdd2853c863150c5bbe2147698 *R/gdf.R f5ef3e8895a346a4fa31fde47141b714 *R/gdfnotebook.R f79ceb4ced41353f337fb4b1c57d021b *R/gedit.R ff0c32252cf3dcc0874394473de5d4ea *R/gexpandgroup.R add8bcfe2c70587597d61f9fd9ccb518 *R/gfile.R 2a6f5cb424b0f0471177ef5590ae8aea *R/gformlayout.R dfd9be70aa57dc192e701608552f6346 *R/gframe.R 5254b38edb8182b64597c62dced4c607 *R/ggenericwidget.R 0d7a647b6eaa7bdf82b35d5199428c26 *R/ggraphics.R 0e08f36d08c38927c5c9f7f166772539 *R/ggroup.R 5dc0b457841f451d9bc289cd2b4b9a9d *R/ghelp.R 8e2991c844d74beef589cf43a3482f0e *R/ghtml.R c3773973b3c684f8b2e872642b8cd65b *R/gimage.R 361f776e00e39947dc2881deca369e3c *R/glabel.R 5f60a63fdab95a89d93051c0e8543d87 *R/glayout.R 0f3d7980a6b8eb8d78433657fa3747b6 *R/gmenu.R 2c0836aae411d1f72d44d0cfed1dcb02 *R/gnotebook.R fb2eed4a5476fd08ffed58dfb0b5be8f *R/gpanedgroup.R f098af4184b9b6cf271255e768f63536 *R/gradio.R 97385203638a6e4b046e2c47ae71a926 *R/gseparator.R b5ea092f176ccdd31cb5e4cbffc2780c *R/gslider.R 3128400b7666b6d2cb7237e504a11b85 *R/gspinbutton.R 5b70b9f4b83e9f5e35096cdcc2993cf7 *R/gstatusbar.R eefa0bf992ead0841faa4939fc3adba8 *R/gsvg.R 6def46dd169cbf113796f0592b7eb638 *R/gtable.R 2b7cad943f20ff0cd237aadccae9c48e *R/gtext.R 4f091b4422b5b8b464f048e121c11258 *R/gtoolbar.R d36c7aa88be308b77e02a301d6472bdc *R/gtree.R 68fb0f970115b71d40a20a0bf8b12794 *R/guiComponent.R 24cfdcce57841af7ca820e8fa3ecb1cc *R/guiComponentWithItems.R 7dc9d6276024988b7cb8e9b5d29dd6f5 *R/guiContainer.R a6bb0ba0c960f8c6500dd27c869a409c *R/guiWidget.R 4f9fa6c7cf92e460ddf0f025127310ce *R/gvarbrowser.R fc5f821a965092e30ee71dba5301e9b3 *R/gvariables.R 2877066e8d8f3063d54f328ccfdb52a9 *R/gwindow.R c320a2a5713436876b8bb3169a054136 *R/handlers.R b8860fe15d8eef7e3abe6c2f68667eda *R/icons.R 8d3597e40fe9c1bd0f2c9c6d0252be7a *R/toolkitClasses.R 161370671bb747cbbe7d924e9e19d6d1 *R/zzz.R 805b3b8619f7404f9892821331c2b85b *build/vignette.rds e497f137939ab6b5175613b615a63d41 *inst/TODO.txt 177a6caf58ce37b07ff9ef313e363926 *inst/doc/addingToolkit.Rnw 7ad4270b9849d58bb0d157b07d62d337 *inst/doc/addingToolkit.pdf 0e227d5e275d514ee1e508fd0667be86 *inst/doc/gWidgets.R 946f868ea2c8c49cedceaadc6c834ea8 *inst/doc/gWidgets.Rnw 43900f9e395463d4242053b2212446e3 *inst/doc/gWidgets.pdf e9ccb6ca944bbc728017e5b3fc09d9ec *inst/images/1downarrow.gif ce9ed0824f97365131503c32cd6a4d07 *inst/images/1leftarrow.gif 5aafce51322865a1e7559cd5b0d0efa2 *inst/images/1rightarrow.gif 17bb42d5ece430bfb36898ebcb7e80e9 *inst/images/1uparrow.gif ee490d2225e6e729024ec1b722a6c6c1 *inst/images/2dlayer.gif 672667752ef7f8df33e25b3daa37ba6b *inst/images/3dcontour.gif e0a03073b7884441bcb92cd6931bd2bf *inst/images/README 672e64f5b267a1303650eaa261c60579 *inst/images/Rplots.ps ebd243d199b918246abc8a9d482e4b19 *inst/images/alert.gif e2ab7a435977637e8372f59d2535508c *inst/images/arrows.gif 4f7ed130aa581d5aefaa9c823672bc4d *inst/images/arrows1.gif 06757b29c517da0346820b5cfb7d5f8f *inst/images/backward.gif c1bb28e94742cbb2a6d6a2c21f218092 *inst/images/barplot.gif e6e4c5340127e32b672c117dfe4aaa4c *inst/images/boxplot.gif 47e3ae345272dc387c9b0b84817362e7 *inst/images/boxplot1.gif c68cc3e1c7050a13f043664213742f47 *inst/images/bubbles.gif 1d22a068a5ca9810cb2ebbf6a06186f8 *inst/images/cancel.gif e4e63b50b8c05992cf66356bc61d7120 *inst/images/character.gif 5e161ea62bdc7af369c4cf38b086664f *inst/images/clear.gif 50034d2e06bef1b7d3c2de54669ffbe4 *inst/images/cloud.gif e5632c82cdf26499bb218ace143474a1 *inst/images/configure.gif 5593605624954c9ed6276e1a0f6deb34 *inst/images/contour.gif d6df67fdd0c46f09d0667c6e97561cae *inst/images/curve.gif 094de049b90efe49a1a8af69dafad2b9 *inst/images/dataframe.gif ce0a36d7a9473efb8b23caa6e133c01e *inst/images/datasheet.gif d0da60c6dc8d25c73196d8b7dd682d94 *inst/images/date.gif bf42ab68d23dd8a74aa11690a67c8f58 *inst/images/density.gif 5f3fc12fd73c4a19c6d8d1b83bc09967 *inst/images/directory.gif 74ba918be4df771d9cdc6806ed48859b *inst/images/dismiss.gif fc7b2e70efcd13d6cbf4c67816d2c863 *inst/images/down.gif 48ae201b9e6205b82cd99e39465d652d *inst/images/editor.gif 1d22a068a5ca9810cb2ebbf6a06186f8 *inst/images/error.gif 28609227d40b8547f6f4149d3f27d4e3 *inst/images/evaluate.gif c85a2739accc26ab02ce662b2d55c82d *inst/images/factor.gif 1bf690bb6527578de6412797a4388b8e *inst/images/file.gif 38ca6fd1e76fa31752d8359a88a82ba5 *inst/images/forward.gif 365daf46da3a63c6f49af6ab8d9d0666 *inst/images/function1.gif b0a21b2778d2a3b5ac62bc607e117d3f *inst/images/go.gif 2c10d8db7746b4d8c3d60029a6bba2c5 *inst/images/graph.gif 2cb64917327f642fbc421791cdf21d21 *inst/images/help.gif bc5f8daf7d927440fdeb4b152fa59f7a *inst/images/help_topic.gif 372bafb1ba465648e65ee0b8108a4cfc *inst/images/hist.gif 6886d5bd54481d3c034f4e04e9f56437 *inst/images/history.gif 57c8f61ba91d24e48f5aa2b6eb2203dd *inst/images/home.gif 044f6f6108dffe56656c243464e2f085 *inst/images/lines.gif 693ad992b646299f42e1548a738def59 *inst/images/logical.gif c3667dc627553229c246fa99356babf9 *inst/images/matrix.gif 0a43dbd521cbed25bf4a014e564631f6 *inst/images/newplot.gif ecd419a232df78739fbc039ed46df874 *inst/images/numeric.gif 3d27c0ffd096ebcb53d0b9d500007810 *inst/images/ok.gif c610a56122090bad6764f6496db1ddb1 *inst/images/open.gif 0cacae682e76685f3ad092bf16e4afe0 *inst/images/overview.gif 4fdcf1326554d18ed6c3272b9bf1da76 *inst/images/plot.gif b5bc30f4480866e793de54672f54b120 *inst/images/plot1.gif 268ae111d723466df509687dc0c62366 *inst/images/points.gif 6e5c7a3ffe67a3c7a2a059296b6942ca *inst/images/polar.gif c6af8db9485a49de45ad76bb0f490e05 *inst/images/preview.gif 3526092ba2a87c93ad00c524614c8197 *inst/images/print.gif 17b71e4a3a156c11bba87e6a579153d6 *inst/images/quit.gif 4087521347c0b71cc2227653800dc095 *inst/images/refresh.gif 40673c30cc56d1f850ac24523b55b6fe *inst/images/reset.gif 6d6cff26337f136b4375893c59692907 *inst/images/save.gif 41c5740a0c4cc831ec01ac7f4edfb0ee *inst/images/save_edit.gif a15403311ae0dbb8b2541965d845f42d *inst/images/scatterplot3d.png d4ad5b075a8b247991eefa2526b12290 *inst/images/spike.gif 17b71e4a3a156c11bba87e6a579153d6 *inst/images/stop.gif 7470e1dfa845ab4b7d235e411e9edad5 *inst/images/subset.gif 20f4430a3046d669c6da3398cd1ea3b4 *inst/images/symbol_circle.gif 7493a12b00650640ab05e6ed812f9bf5 *inst/images/symbol_cross.gif 364eea61f823e66aa03d88cafed3aa7f *inst/images/symbol_diamond.gif f523b8aa74158f0d9bae4b80fca70160 *inst/images/symbol_dntriangle.gif f124c82a02f762ce6bc38d8735c3d168 *inst/images/symbol_dot.gif c7f81f5c962fb1e889b874d3a00fe8ec *inst/images/symbol_impulse.gif 7fe2efdb6a6b020717da2b66325d772d *inst/images/symbol_ltriangle.gif cd59512caf8ddb2b3f423ba8ac7c32b9 *inst/images/symbol_plus.gif c393de7f40f3a9c9b36f9e24e8b2bc7f *inst/images/symbol_rtriangle.gif a73fc85f52b09f9a1c13dbb5ca3d346d *inst/images/symbol_square.gif 49e089518c2d6b2ba4eefc270d53c5fc *inst/images/symbol_star.gif 20840968cefd10a1042c4f00925c7e5d *inst/images/symbol_uptriangle.gif 0cf3695821d329cd4c06759ef3b81f39 *inst/images/ts.gif 09e5a2457d75e5299007c4a889db0033 *inst/images/up.gif 7912f01b80d99edf7794d462b94ca6c0 *inst/images/zoom.gif 22cece7600d78c82d52c0a51f6096ef1 *inst/install/Installing_gWidgets_toolkits.txt 832191271e57a0c05d9029efb28b5144 *inst/src/ghelp.R 78022fb8bdd221dd8b5f432b640cc0c4 *inst/tests/README 6eef258269b3264e79ee7d0c80adc2cf *inst/tests/ex-containers.R 27d77b3e68d4f1e57f673657fa12d7a0 *inst/tests/ex-gbutton.R 8813a844d7371723f0dccf4431a8d8a2 *inst/tests/ex-gcheckbox.R 2f6e252b47dea861f7ea459f7e4f12fb *inst/tests/ex-gcheckboxgroup.R 51ea990c21eaad6e553b732805de67a7 *inst/tests/ex-gcombobox.R 778d79d808c319c6c6474473d35c45ba *inst/tests/ex-gdialogs.R cc3bb5c24b3361ebc7f1465b83872dab *inst/tests/ex-gedit-gtext.R 153f048ceefbddf89092f508f61e5ece *inst/tests/ex-gformlayout.R 95a7ff221b8b6c4390728a2e8c6c3c44 *inst/tests/ex-glabel.R 8ad6a876264c35ee19064d09c5c46400 *inst/tests/ex-gslider-gspinbutton.R 4531604cd7da4651156ebb52b94e0438 *inst/tests/ex-gtable.R 0f08ab8d1fc85330028573dcf56129fd *inst/tests/ex-gtext.R fade9b6ceb3799ae006a10fce46d71aa *inst/tests/ex-gwindow.R 288a5efb7e42ded54ddaac363aee7ade *inst/tests/test-gbutton.R 2b147a7e6e76a557e046af0492a21637 *inst/tests/test-gcalendar.R 84f0d8f273aadcf09089ce3b684dd4f9 *inst/tests/test-gcheckbox.R 251ca9854af8c9cac1f5e62c194a3f2c *inst/tests/test-gcheckboxgroup.R 5a4adcb5a1ffa3c5bfb1a3f46924242e *inst/tests/test-gcombobox.R c2c9abb81717efe157caacae5f4bcc18 *inst/tests/test-gedit.R c9a7ce503dd070734f428b41641fcfc0 *inst/tests/test-gimage.R 35f99fa80b3b2f0066417a6bbe9b8093 *inst/tests/test-glabel.R a3c00fc4389240b22c10f0e1810349a8 *inst/tests/test-gradio.R fb80e59c9ad64ab424cad5c8910cdfee *man/gWidgets-classes.Rd 4b8f861d2167435cd020af82be5f2fa7 *man/gWidgets-dialogs.Rd 7a41e7c2bf843c8de77d0d2605d809eb *man/gWidgets-dnd.Rd 4e5a38c0a3457a2052ac86f0f9d1564a *man/gWidgets-handlers.Rd 49727741b9fc9537256e1c0881c74c5d *man/gWidgets-icons.Rd 5760bdd1acc3b75aa83ebe2a58e957fc *man/gWidgets-methods.Rd 8077bbe0adb60b1a6396a22fe77d9678 *man/gWidgets-package.Rd e6dbd92ea28a75efa9c905b5d02d9025 *man/gWidgets-undocumented.Rd 7b35283c0557a4f585a9dc6ce977a7b0 *man/gbutton.Rd b309cca3ddf97b2dd031c59af4cfe59b *man/gcheckbox.Rd 9fa2aa1c152ea91471116c47b8a8cfcb *man/gcheckboxgroup.Rd 4d4683b14f5238bdb3279305c7d194c6 *man/gcombobox.Rd cadaa48f3f9c538fa21d2f7e177b64d2 *man/gcommandline.Rd 7e8e2ad0f9d52c548372d8f577ed1b21 *man/gdf.Rd 80cb41d4c476fa43213b8194dfa70d17 *man/gedit.Rd f4415e080a47d24eb8538800d5cebfd5 *man/gfile.Rd 126a37a94a10dbedfd8e5143e2a1fc23 *man/gformlayout.Rd 29a95530d7d315c48b0ff1d396fb9149 *man/ggenericwidget.Rd bc563191a9ba7951e8c9380d094fa15a *man/ggraphics.Rd 26f57ef70a9b726b06892e625fe4c3a5 *man/ggroup.Rd 39cb6c68650c8cf4b5ec2351d4fbd244 *man/ghelp.Rd 68e28f1f4fe696ee0611f9727d60616b *man/ghtml.Rd 3204f792398e72537c753aee86a064d4 *man/gimage.Rd 0f63408b688e623c5b95ffa830c1842b *man/glabel.Rd c7fa4e614878eaf92ef33878912f3891 *man/glayout.Rd 1b12cbc5b49f44e9ea22e158500fe798 *man/gmenu.Rd a773e184bdafb87688b7a2a0dacd425d *man/gnotebook.Rd dfc64d4039d3bb57f26aabe89cff5b9d *man/gpanedgroup.Rd 544c9cbb99850383940c71ae49598be3 *man/gradio.Rd 03be3ce749cd425373f7cc9a39ffd5a7 *man/gseparator.Rd 5c963b1d66955f1f9badf75d807fc51c *man/gslider.Rd 0f3877b2a96f08ea2a5ef4474cd10063 *man/gstatusbar.Rd 3e1500eb9e9004fb400289e504e6f473 *man/gsvg.Rd 779bc241ff05effe5f711d2b56189464 *man/gtable.Rd cec8afefd904dc8dbd7fe238c747f0b2 *man/gtext.Rd 3d656f4b481e8d196fa0f6eb2c539041 *man/gtree.Rd 569f419b64a9d011a2294380fc33edea *man/guiToolkit.Rd 354639e0af7a0913ea15b0acd0c4ee85 *man/guiWidget-class.Rd cac8f233400ba159ee6299b037960633 *man/gvarbrowser.Rd ab55ee6b9dfab545c1b31f8acb326a03 *man/gwindow.Rd e810248292f761a6509b47e98b24cf8b *vignettes/Rmail.png d41d8cd98f00b204e9800998ecf8427e *vignettes/addToolkit.R 177a6caf58ce37b07ff9ef313e363926 *vignettes/addingToolkit.Rnw 55c080f18de7078ee541b0159718a949 *vignettes/button.png 1318d535a5366f2d1a130869fa869f42 *vignettes/confirmDialog.png 7b8368fd7654ba3e604320e15fd802e4 *vignettes/doPlot.png c020a72be377876053f7f89bd1b51fba *vignettes/draft.R 36d362c6015e4d177f72492d861bbb0d *vignettes/droplist.png bb8c2808092d34e03719c8ad5efad252 *vignettes/filebrowser.png 946f868ea2c8c49cedceaadc6c834ea8 *vignettes/gWidgets.Rnw 8f5f2c7e226fb2a5fbff02013ddb0599 *vignettes/gWidgetsImplementatations.ods 239ba237dbddbd57449727c6559bf1bf *vignettes/gWidgetsImplementatations.xls aa631cf503511216bfc8425d8c9b9909 *vignettes/gfunction.png 4f6eeb33a24c570500da668cb38ffbc2 *vignettes/gtkdensity.png bcf2b4e3d5e5a87c015c3e6f812f5ede *vignettes/hello-world.png f8a792e432e595c4c1d5160323b9c6c1 *vignettes/helloWorld.eps 5c04715588b44ddeaab1581b9a809ba9 *vignettes/helloWorld.png fbbef491c7fbdbe3ed05d4024c2570fd *vignettes/label.png f7528e61f748f02d62f10e45366d86d2 *vignettes/notebook.png 3086aee12e672337a1d5d2945b5ae739 *vignettes/popup.png 3f582f3353962d4934acce23bf5f4436 *vignettes/radio.png 7476ee8f39d4be10f3e6c6e5f95ad785 *vignettes/testit.R gWidgets/inst/0000755000176000001440000000000012377442527013051 5ustar ripleyusersgWidgets/inst/doc/0000755000176000001440000000000012377442527013616 5ustar ripleyusersgWidgets/inst/doc/addingToolkit.pdf0000644000176000001440000034404012377442527017112 0ustar ripleyusers%PDF-1.5 % 3 0 obj << /Length 1601 /Filter /FlateDecode >> stream xڍXKs6WHΘ( Hv3;9@ɴX] )v4A`vCNEyμ~ *MX-tɊ^\,o_sg'6Q481YaE:^y\_;QQ-?B;e7xvbUQ:xeʅ?5 c :0ouDW̧CeERLRs#7`Gh1J?x$Vmv\Y.~:otc&'#H)/"V\ܢ?8qF:>+IР4WGw?Cf>wl3\!g:+j+ZJ̑'{p<9oQ BDRqyKj^pxޒp2$#7Nn8/H(֮ctgYTmBe 񮑃b)`s8HySKҴsD)gq\>6c<5r$US]`c9׊ hNx˓ӎH-Z wE;%:-ͰR!՘*L{ݼ&JG.Hl.W(ej|- /!=C Wgt"g%A5bv!2PA4B=a8<:v0934ՍnZBg'OR(3/|p( rhqhWU!6b\uKv4/,R'+A2=&.DVC`C70^@S7t+Q6t$fڲԜyUU賒8؄hV _- ƖqW\V{0 IcV߅6i!$mOz}_;4viYŦ Y- ВXwdwH%ApJshD%Țs);,os1.qސ \K! 6u5.XPSFѵ9uOF0 /o'P 3{.#QˀcTp80c_ezjTpu`*4"Xop-@/PM7b3ϚR| %SGR(l^sLi~0(u]zgPņT;F; MޘZt>C~OjH=G[Zow[ endstream endobj 12 0 obj << /Length 2032 /Filter /FlateDecode >> stream xYKs6WpC@C#䐴frh{`dR,KHt߻/L9nC2AXZ%J^(y8sYIgVuIQL),Njv6s.70numSg;xa_w)S\[/ෆ_\yF[\st[Xi\^=5WYi_23+_| r{ Uq%gr4uءjw 6&FT)y0 |әVU26`gƥijNqfs 47`O7,^<^RLJ8ٷxd#/.d[pb5.z/ù[-مV>^ PX?)1gD~+Xԓ-|$FV(4!L},\cpgS0yxPqkFN:RLw?7 Mݬ9xff)|.#'`"Y_2F"t ]rsr0ʴo`73pzW̍$Dc`C9'^޶yS3&cwŀ2#Hsa{;_Dּw1Θmzʡx ӠċqQ^uGiGnR׊sG|$é Dq2D0uj8cb<q-ka<"TKh ?4chz'AX2vO{)eZW7 ~Fuy,?;W(bhk|M~x >u۹ B/P_35~;ƍqkHK9J W*+u> 5fy!w 6uǹdy.Jdž7Jzf^Y຦򱯍ô"So]բaa{V j .`Мd <.8+%6S 9DhpC&:dLw|i7_LL}PDt ׆>DSϋ'IJiC]'˓T)|-dy]%V,wXoN~^H,/M庣BU*SU5jUIՅ)2͊pJ歗gEzCFnm]pyH ܉+XGYK]P[bсC14OCS-g f I+oX(4N|:RFaxq߬犼0]d+ wrQtPW jxN$>QCp!^7i!8~k{ƊP%o +Dj3@zb9 jENHR¥\hKi+Ѣx i<Ez H9v`75v b?q0CϪMpgx/ endstream endobj 19 0 obj << /Length 1146 /Filter /FlateDecode >> stream xXKoFW qȥiRhRPCӃYT|K.-ҰE(.ggfg>΋]?]EzA E  JdAV(EiX,7E>4\iitΰܙYU  SAKsi=qZuX.h(ZC냕8ſ7$ ́c3ydVLVl.3_E<+fVt+R%Q0e,"ic*hJ,VdY+"3L\h?NJ4c=^Gm 0 XN$LHT\YCorݯΤ *seACBwX!J?hvѢmUcF -$;,ݿ9Yz걶'V #_s%#PY=օTOZRGxYz i|7"9R]Ûw'PqJQj55O];.ɮ}-:!s<7wЦxƜtr͋Pl }]fQS2(SofނKĸKP 2Bt Q_ ѳ!'JrS@ˍ MZiD~?Ӗl2`[UvGtIuoیjm}Gk[3:(EMaJ!#u%hp9sOr3ʩ+C `y䡋U,Oڼs-W6F9!GMxL&W ;Y*ps2-NpDV-jYlPfeb0>}~`eI1< 2n,\⹆F͉[.^3܌꽰\Rs^u~wgKe{_RHOe&+r؇HV[{%jZ9+~/ J=4y*4xqaպg!LIPcH">zl3s3p6QAYls4BI Q[;v"&SHC`]=x4]xj{ޅq1~1T=l5  !c|_q(o# DnY( S%(Rp2y> stream xXK6C@_z]t mO.rhzP,9fZ8EPd-="Hi&Jo/R~~=DRZL: +D:9~ZyX/}I%*DaLF4K`s&4- xqn RRzHǬa^K(DpD2?kCD4xӒgK, i1%!r<>*G”q8hH2pt"^l e .&{ BD4(DYvړf4iIOKy pbӭrE0ݪ.[Iȳa`OBɂg{]^>kh"[^(,yh̗zGBb})gB^Ɗg͌!T\~/$gy}ќ_K8lÚy=63$!ِa{L^s|?A*4g\y_tZwIt?!e\ѳO\?DԣәK.̒q+uh/d.-ɟ0HhgA]?Xh#2mh,n;o T^ީ~oݱ=L-/1:\Z^; ,=y/|KmR<ʌ@UߧmK=˄ 5P̻ Aw* Ic!aK(a@="a]\۞rt=|UH#P'D2s֛aLs7i0B- kDQ_DzIJcMvQF#ixN HV wۑ"+)TŠu`#M5R$2[Rdy9XΦGU4 Yvak&\uHeptG/^RZySUh Y{ZGwFǴ䦹3w/ψoT5ʧ!EoQ(7o MU S GS}-ꝲt4鋩C MֲٔeNCt}qz`f+=d}g=썺_{u* 5(Re,.݉ endstream endobj 25 0 obj << /Length 1480 /Filter /FlateDecode >> stream xXn6+ae 抔HK6aŒo+8A/3HKvԃcp޼yxYLgg.qr)h8gL8NGr%2lODʣb,XdzG+)aBD~\̍U㯳_>\*{T?k-m_ZX5DLi@w72*Nm ?;·$L&5p6W[Ъ mqF)_osXGSXX½wG+&eR \F{G2~yxƓThy kO6^a :Yøw$SaZ-L:l14&OiE€3.f&ԆA~#VqpT\Z,ЊMs{Q(آWFÐgME)'sz~ëc:4Jq̦S #DǗ-yk=%,an ^IC)DE?{,MK2G$qZ WtASv*$x%P&:ȌDf\"iڑ} YQ"f6nwUෆE}5TWEk r ]^M3\}~ 0G arl7E =W W{^{ٸfL*uDųs_ӥA L ^u'@E5uPȺ,'C2vlG%)Yz%؅?At0oK\& "?RM>uƇE^}W6|,bul=‰e^o@J;> stream xXo0﯈إZ/v4ViĐ8c]:l!wv&r<{n,0xs|6>8QPJ2Y0^ Iy$)'aYw}D{ 1<\v9c#F.F)Hz.VXq?<9fpub2(̩;'I'ϡy1ܻ KI1.g'#>an[?t3S`9sܿ3LvVcK>si!]#60puC?=]&ۡ8OQutG4,*=&w <gV ^mC*tU^W cEzRp1"{߃ {e~oDq|9N" G6FBiJUIiYL˜ 1LRJ{T ';Tc?7&ˆrK6> stream xڽXK6W9УmI-Ek;kK]7(;C%J+).-|zk/~|1<E,S{/ 3&b/N C͖;r74 ^70VfiK9w𳀁q<9Կǟ_tU @#3Z7C 0C c ;"4' hdRƍ-1ZWx0rI-%X+ο (r6WE5!3nHnֱ zH;v<Ņ D~$R4OxٰlXv߉W60neU$uKO> -?qx>4 idoNgAdL0DqSf<?NARYnɆ[+FΌuQџ\{l%M.i\ѱ [zY8s0b@@N۞t=6[ &KHƣOJ cM=Vݫvu?_砎ڶ\[}yChNKzcoj7w ˵Zꟶuâ[]To*Ӷ @RjMֺQ:4b i"!`.vGNb_זf_!jc:G,RRoͫQJL0l-//%Ƣj6.tW(쳜V9ꖰuڥh K85ɽ>فH2W FztNnr.` 4M$A6utS!7NP d'ar2\ ji`uX'IMI$=p! Lp=l{XlliRemH{577f}aL/,g_ EbpVb:%}F<ț)XjU&I&ux{Cjr,OQy-VwKR2[?_i۝q%̽a,gc1Ǟr̹^|Է{x4p`PM`eP?ȋҌTy[tZ1wҔ{/%gR$b#  # $ъ $1#R-'"9>5wƯaRĭT瓙XY&O1R]thRC@*:6F"!#76?0637n2aM\yݠ\2|0C*3cѹGm*:lb1,TS>_HBB^fRB:T/wGU*&0IZYRCHѦ^3gہ61vP6RP5GR(.D&Ju,7 &8(*p}v+?w@KI 9O- endstream endobj 37 0 obj << /Length 1167 /Filter /FlateDecode >> stream xXI6ϯr#J$q 9=ؖlODZ&NQGiـ큲H={zUߗ7Bxx3β{I&XNEpN>IG+_(+v3/+oVWOoQT*2+|5dZ>plyȒ0,ZJ(dRNq^ECU(#*Mɼ ?+%T\iYg^l:M4eN#XXj]|> 8*ű44#4v)O)TORH*!ӪZSG+sc 'r0Xc Zg݇--/!^d*ص%W@ zZ`sbZ^%r1«"Uf0+9trQeq ېl`{8*2D"dDY[ܘ_wD!0DPBz/:ydYAġS0s/lEI Pt_}K.6ZX5*,wrd̅KU|;CDWҡMsYn^s(x_Xގu8 lKQȿ-H!p-τi{V5UgI]|ɴx CUf8Kܚ? Q?Iϒ/ʼTÚ*j(n{4 %woԮiԎ]gî]M4'ܪk65W]lu"Z&mDncpxi[&c{̀NT] B#jṀHN> stream xePMK1W1w$^qr*XjMxɼ7yI"l!'l@QA2abpX4)҉rkbcw;{yjNݑeu*aQe/$ 23l _Myzy}# g{diL;pF~n r,ǡv纺O endstream endobj 34 0 obj << /Type /XObject /Subtype /Image /Width 239 /Height 158 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 4057 /Filter/FlateDecode /DecodeParms<> >> stream x{pTU>;%ᡮ8:# 踏١ZS̔5S[:n[Xly`#H ر'ZŽMO,f}HZ2>639648Iogo}uՕw~=d6ݮ7XoD?FMgb-)Gex3 "N:ÇmVkmu_vdC3v~om.8g2g/BDw!1qtTtURcln}v51OT FHyzM[~ǑAmWWW___2svOs}i'Mu42g#"=_uy SDsDM-1`+Iov@,zIga \s_54 ]]V9ye`Tn.B$rcP4_kKy5کo#;hs>SKD[[ӳ~L Ә=FYSͯi8svW>u?T&M| :I]:~v7)Ƙȳoj_U]#QG x|ș|ڗM|DJ'j#"x}Q*2"Zrs 2i\./3<}~ߧn\q,^3"r4uhʛ*H>}|>U)G G/<\zo]vhE^Rݳ[;.lJW]X_hTڵ[K4?E_t \]^k"W9F-4j$*=f'ʣZj ׬_fH#r,xW^36"X6ݧk(\K= Tqf2Id/ɮ<(wͺ{lm}S3bOzcUzƉ 6{}a9;/>jY8""򺜡>rf{~_\TbSFMʑ: :,pvw0thXWmы.kll,{{# rW<`%tEKX U%=D7 ?DtߊuQ}EgPl MODjx&juDt_UADo9Zf._f._Nf:+{N w6K`snW~HgY;qE{QѸQإo""7n%P֌2{鑹[Mnq+$2}r^S"-aED%yĐZ RI__q6Ʀ>q*f2AKƉawtALDGkK%7іQ90|ꦷ:b16Ǻo^s1-md[9]m^z(:_CX>Itvp_e$b{lMAeEi㭝}Ñ2ޑ\͝ eqbוf"4JDFlɾ|CӚ%ώwk>"jn$x z1^؎KWqzAU Lb&,j˓}Ng!R: T3 | o ~&B_>ҘsCP.9^<>w4˭K  ~oipq7ˍeuyO}6VyU~A. s&Z&r=遼=~O~WlҬ523SS(Α_h5?X]p2 ?,].ެ`vQ9ՙF@ʡ?-[0?Ǥx}c{W0uwKyI^O=hۺOL G104Ub?K:&*sGFƧ#E"؍=ﭲV[r{:1Q-%t!X،Sk,3ޔGwfѪ\p9G<1u3Ƙ( hddGzWI=CDL%}lDIFK }dsV"-D4vkb5ƢŒ!GDjPX:g'49E"8;: v/NJDzMg+]厡S{o':{ϞrdeG;g>.DA6SBwcڜAcl8^N)p^Ή:qYa@_jPX 1bHDYgHD fk>F}9JSs,0ѐ#VV"rr*I}Pț^n^\f|O&lY*8.ld3o鉠5fEɛրLmdK9> r00Sq(|W vV_:@(J 5g9»M3EZ}ijFBL :B@jjjjP37_P> stream xڍT. Ht34HwwIwC%)%)%"  Hw\v=׺wZܜfnv;;'? q)U]ۿ-Ht?D φ/ ll/O#u"7{?@{-^6/:Zlo:9W˅;ZFO_K)q]lxpll{9sGeV@/')7^r ?wv}qX!L*/`X%AVU_`__`5XA/:sK+##@",/J '7RooJK):~KRoEz}GJ/N/o=_)ҿ<^[_x@~/<\~/l 7 MKBsKQ^Z9s7K> /y̑悡Cokĉ=ƅght} n) Y!)C+WbO>-Ijm&էڐ''>}%E"a}r{%OƇ}'Yhv5c4sVaP,MY%+3)SO٫gr~>?8W+49\ H_]aNH/ˇGY7t`j)F&GL$066h$5r: rxM ]:w+g !vG_BE;w#vSx O'>_0s5zuޞML:"~4;ќ"[S›}z&.Q.Ey貱*̏g-E2T\|#;*䃯fXJϼ%@Ԩ|:URH=j D)㰷JU *)rN(ɋ.ygc YV6Q=Z# ;WN`g<O4WN{. n~+W%S!N_?Q4,g uzKfHd ]MiR{G\^;ˬƀ~%J?LMDz6푵\CTa tz?!FIh8v>ltW#)v$%]:@Wܯ4k%F`>Df"dm)}ԞYeTj<My:vwA$LZ^O!;p1{+]_[Gʴeͷ9r֌}E>4;owDLjnV@8+6H˱1ǝO}|Pi: R( YiGe_X JH%?),MDTe>^W-na4!l!r%y` ^ 02.ˏ*Ìc81=!fn< RRzxUDxtMt"noCUa7$z9QJ>]ZD+!\6 x߂{^(M "UW2FL: pqH75*qM(IuJbCIwXmXVL8+~yj㌧>X٪ 4^( Arh/g3i8xmrV>*&W'ouV=tfvCuR򜮽9p9%{^͍D+l3%#WZt˧4a*vjWX!f3񂈂 }RԄ}"GkN.[dT E.rf3%DP$<ývqAʨSS58Z_(*dw7|]>Z*3^VSU'i8}O`MCS ;1a4yB#74u6 ss5ŷ7Cn*fcǏ&HOrBgp(.G~nJe:gP^총 _RD'|u7e e '![NQN!)EJo0q|H^u-cF9*W1pԼ}MУRk jsKbGCn%w\0z<$-JDL|@~ _VSP]Yu&/*|Ǡt-DDeL"PfjYo5%OB,"wo3p#|EKժzzjzs$ ' U+FOG3kS w]nn8W?K]"n5 *ljöcDuopߴ(ٜ+Z^X̲@&1GMc+hFWpkOxJ%xsP 2' n8zn12A踅"Hj0tc\1W se+7~Є;tyT"0ӹt̙Ͱk+2J* R.i#jĭ=!>HAkMUڄ䀹]O=ctH,[ǜ&Y`Zَ )|X|=Q> h.,㥓oa[9> Wun.uʶNklݞyP8*-dr,z|e$|q/AMEY.4ڹѝxdb>U O ]sRAӒ'f_BrBK4Cd֣FJNQ({SeX,HzHlT5ʸ_iꐢt#xXbbIP&&K~>h]!E0Iب3' U03qTLn#D]#93CN*%M4+~f6ԬVT ev+(_-40Z5,DaxAZL7ּ'|J\$H޻u붿 WqTh"fm&7mE#_rP˒Bj.'1X},$-7!u{կڞrb,U MG]J3tLi<&t|džNX2Gmw4GxLkn}d;SYJ}ښ!Z[YC^qՋc_@"itB? ô+q{U6`xyU<z /k=ϔ!p ;֯ʘKib6WEwxx^;uѠ|cEZҁi%5O|nC̀Q|bs32c˺ɦ#w[%GiK9TuYj-z=jތ[0lwF}$(ʾ+;١[gR EjIc^N&d<#2f~{#*98'ecb79߫PyJ | ^*-+J酇a/BSal8P7Pү}|c\ 5#i,6wtfrϡ󣇕c{ǝu͂n8FV{)Wa7۹(pY::mI콰(р^m&@hCj WMn%ÀI=(z*.)``c!pؘ4j*S*pzD5>4:#PZ}H`7f5}'ЎC.㕙ШD ֵ{.n2&B~dl:&}ggS(c&tes->ͣ[>&u$^>ݠ*mEb3,!^u0jn7>~1CcKW( w6t̓mXwdg-o]M_.J:r,ý2ڌ ó,8h}S/L)DsDPW2_d;SJv;5 z y7Any_į N!>(M}V~WHs1Ehu>HKk=ɓҹsqcVgx6[`;=^eaL$bezM$#4x B8h{Ѐsע+Uu j3ͱW+y%%qΦ?Lo1N'V2F NG|A"QR$[?YmPjcY?qhhp/;!04mB.G-?oU1hĵf|ʹ4x[f-h{w?WV|ISq[*ӮTE86zv{HJvsݲK,W 3aKM^AJ_4~/m3VIEI_:{hZޚ@F ^R{SVM4_9I=M77B=7)OX^"V>/5h"%C)+ 3;y m]g!eۤ4( B+#in^@e35s|I;T_QZ=J;Gj,&<VWFivZ34z0VzhR$)LC=SƦS˰,Og/vr].8T}ǼS;syLϨBʁRrppi傖͝ hfdl`8Ϗu.>ǝ&+DT }rvWcmq]MՉQu 3r Ic#\ڧ#©}^-l( ;NSZu_tW=۾Sgn}8Aބ)܄˥g}m)QNf@wA`N<r ])qYiX5^x:E%dr X=`#v!b`y%I8ٷZ,vg/,)pKEB`hx]5ۙEej{t[,VBq\O g& ݅Ch[=D?VH`M7_ZE-ƶ,mHM7 r 6k~͒'ij*l6!}9Xι[9""Xs.LD)QzEl;P>;  &,pQ&J_fGYF)YS{$qf&=sX EŘl~[Ve 8^ [X/3~G+^Ə';yN(Q -=\?bސҭ`-^:ܐ,& )b[2>|AG1n{I46O7o,>й`9 }}Up/;;E |CkZLe( iE7T^[{T#~h] P@ظ" GJDOcNڱF>LZGl)Z۬T8AH SxK`ab|rة{otJ6lRґ ɋ'bU[L>PLdɹTz2-YPrfJ{hm mRn^q+Zc?ΉGY[ uI*VelT? q9<1']{bqL:dt(<@w :pf5nYh?*]*#g$պ(F[r,N$ђ+FŶغ*5sD jJu0Qd^JiHr8n^꺰11C:TA:v=$\)^۵1X>W!m{Vi@+ji>ް@)M`!8D Ҕt,fIVg ʘgY"#fdO*,V5 YӴ,[OVni@>-Gh^|A-655rCuhmVRUAV ?WeR EG?YRVP1J%)u@}ײeaŮrMYHX;_ad(kE1[\h+uR~Q$k< WOƸdL B.n]l{bd2`yof7ĬSzmO~ |ER{kjHF1-a*w;Œ5!uʹzc>TTIYBSjdϒѹL7 r?mp/Wγsᄍ|#& j[#ۥGkzL'DvddGE4 ˢ!W4n*3^bS(k]IoE9SQqoJ9d͡:5^a<>JA.U6#z…Xx7?cP弚˜Ag.2h(29qݿm\] SEe"=G 7ay/鄠6-~31nhb,eYU̍gu 삘%úY=Qg9~,$,j1LRMd_qF`) cd Ǫ Jԓ{WX=,#J-bBNc'cLkk=|`]d=DLŬzE0:|zZtt~љ]f\oQl&T´b p露PQ"ompL)j:衦Y{ɋ(;^,pC1OKa> E:o=q4#/(Zw+fb0el4R᪸>!IʾQC_=Voy0/sznHqeUBViXcnU723dS,5JO`S n5 zT`U;KJAq}ÇUF#.TI1K#EuX#UW'EIGRqJ.:/%kҸiJ_L@_[U-eƮxqn!%(Yri[cAV#5SNG }f}u/Y8k L[8?fDXy[2sCBx6AЍ?lAe 󑜞ҏR1k oQ0'L\3 C?s~U1=+V2:>8ɿnƉ"ӭ\Jo`֪#onvsE|ϡM_ Nt 7"BvR"~.x Y80_9?+5;9yWF]ɠ+TrƕsS iI.>h#} !LAl Q 2N$n0 PF[ p͞`kTk:pƩdw;=g4V!5X,[E6.3y0Gc )Gɥ|o)xNJL"[~7v~%Y L~ioJߨ8FSѲƒ0d;ʹLڿ.5#"YC<w9uQ)vi Άw4*@N}N!Xzxfgի <҅q̼$"Y߆䙉EG$nv 9ÆW* <#eЬpBEfDb]9#{7[퓉V"/-:Kq!+3$-?=(}>݈O xp\ʗ:^Ćr#:H]3;^Dͭ:|5t@.V_iqR &ZķZz<;Bx{rYCHE>eܜRwmT%ȟfɵyH\א9&zWvo9E}Y9D!ئ? \c\@e\xv)/Υ,2k\cx9pm"`F+!r'?xIy]6p KVJm-Ը#;cņXyS &&t\SN.gM>fɫhϚ‹U׏ C9q".W.N9?DLIgy_$3i"K>y(Wvu[QO/`q64pp޳O~v*4`+,ZQ,x<)oðǤ~~1ޅUz\u1SiTs|hB#{ <{uu=uJN#aXph 4F!~qA x\TqX-00P*WiJ>JDǠBz锱sdJ~eSw=x'"W4|ס`cC[_0T>؄m# :vp.S-0L=` OkZ̜tvx[Xw͎Mkql2Jى|{4ޔ[slڛ!©2nbTG|zP2GC2^{VI=zA ʄm y͛B|\+l[h{6o ȂPXmz![}֔} q1uSdT&RuEhE&oH+ӍWQ%f+3(A(fpqDIKkAPe[ JxoȂ9972&Oۈ:'Ue]me?T !MG2h^6@,`d+ lzy[kŒ\f}-D/7~L\C>ŪKk9&ETTE@ޏ/j-mgD?&'i Lt!(LwTņ:PȻZH쒎C[+|V,.";˱! 8A-Nm֦dHsj8gX4Z`IƠC&g4 )e,t*|Ua/GY7Ռ]vA%'.i+/idϛd3|fZ|Ԛk鳫vׇWoƪ G `WL{FmG Ke+bRm8 MM^G%n W់_W*wa,^e` ÔΎHy=ݞ }>4[ѴFJ1Tڌ[#/[4JSRufLJGRCl0PEctWq9hm|֢ʨDȬ28|g(sxsSg_am$9{:ceX_#ryG6>=RXV>㺗tkJ8BUGs11I öD5:''qX"Km/kGP!rV\¡FߣP͓4Zq˾P}LWK=鿰 =M#mL^Q$@6ΚEs'*[ԏ=J{器"kwJUv?wƓyӼX }RJ'pk| C5#l}!]o_\4\DaXAw 4nQ?&]Kf1j6 CR.K׌l%cv3KASpnL" \B`+q;Ngiǔej긐Zks1,`!PG۸GGz_ywD`TjQqkG=74t͞QQy܄Ykۼj5VIl ohC*]x6a`4~X+X#{HhjT[-xH>wzF¸N!7I:E&z<;ܚ>!SYsRC \!zLSN͜Q\v]8+%`wm܎Wڟ{3 hb&9`Aj@StIV-oqZI[x [owˉ_)e#:|yGmkyx9װK|&.-pTĿGUY̅Jt'͂l=5=`0eDt;?k -m5W kx|`V[]jd,|?5:_\WyP endstream endobj 53 0 obj << /Length1 1910 /Length2 14497 /Length3 0 /Length 15666 /Filter /FlateDecode >> stream xڍp$ ǜؙc۶m;۶&ض&Ķ'_=_}UY~ZkW) \"rLFFzFFf822UKb82u DF.2Q#;9{; `fd7@ G:Ñ;x:Y[|@iB` d t41Xm?2TM,.Łݝ֙ɜnbP:܀?l1#ZX:%W7sq7r>6&@;W;S#9@EJX/Zw`godi9PwpٙahdlofdicdagFq!%98Y:8;[A0,fg*bok sq>QK'ǵ{2Yk;{w;￁$L],]R|]l\,#abGxUOJ? |f$f8og#7 o"8&& hniO1/|'K11^v6_aa%1W',lce112RE#˿WD);3{_>.?< ʿW ?fguM>?/.(o wSMGmdki(|r_S _,4tZ)35Z:[zM-]L,t#P@ѰX8W)LMX-P-QӇ/ɹJv?*?gD[֒-&-2`dS}5 19F]@nMRFSd' G@~BF\hv!怊c# T(9&|Q|ܝX-)J%ԧ=^wh2~Я7&q9ksr3/d$.S`P#&xNr "/+ ԃ$*{V_'W 5H FIꆙ9ߞo~&d[mm nD:Rmuj_0Mp+rcݼٷu`N#,8|I٪Z22?Gzi$Fe"D%r:=(#e(SkإIImOZuz'F~Ȍ/3'zKӺU1`{m&ϳSgS !TμsuOm $aPaM^T L >ArL< 3i,\U8%XAxH$k:[>:aa>ۧ3"Ƅ^|{Gҳd3#;;z[W)1$|asq(,&&DSaOM8BYʵ;y9ݯ 2| R/O 4&pY7[ H˦abӟ- aEնd+iOm:Ř ԅTey+0*Dr mxjz)Iږ5!ġa@@B8PzT( 4.e| R5P;<*;\ra~3d_&5x -MK jnVyM}Ex$B, jSA Y_n^(bbwGȚ? x(6ЙT@qsW~Mpx[ vH|jMtż jHc sT_34bgR4rQ0˝@Үd"Z+G! {b6ZX]g9c"bF^!gےr ?,+p6ɴC.<*^ēыAp,.v튒"|#OZ6cg . +t+{KqH!FH{-,s֦A`beDcu 1P` k2 k'cKHx!ΓZ' kuE')zBefc$Kyѹ<Ota~8oAUkWNMfb8/`{DI%'s&uNWW~KZ28ڭ<a4 aT &q-m|t]*L6vju/B6~X|2z'a/vZ""LO.$e Q2uys<=?mş(DlU=&T#lQwD' U;p6I"Xlw a(%N+vΠVuϰt+r-qjG;sRU :j{!vXx˔Fd+~7tsmNW~?|win,C$"BeC|zApȈemjfJJ7vr>\סwF'f^en; ^5an0P`?o:5A 8qlR±W`8a=UBsҫmOa S݈["œ>ml=mD=(zHaxiY XDGB#fe[y9|ؑ%ԁz`JL?3apgn~irf?l6-PEtשHpl &T&cG'xl‰t9Q%;,,ldAޒV6w\i-E$4ZL{5Rgg|"Mä_xJI$J];`W0*R nO`^\!dRR 61 Br0by d7/فͽ넵pI6JasT=aُM <*8q@H[ D,F(13نS#Ze2Oog}@YDn*cҀlq~Դ M^"SpLyR:Enu4$نj 8t` & _[4L>W=8p[!KJ> H4*3uP6#CvlR,VzJ'2.9@@r3׆b8&kQEwiSԒ(_!Ӄ( d Hؚą{Ȋn /@spXO;_^͟NY!O%=ZͨQ{eh(ؓ2T$O}H8فpfW U yzvq_Ѡz\BOɽ-~a0eJ5VcX<LyzPSCwSK@S>|"ɮ(wB(k]V|Ć@u8 5  @tW+jl :t!Ȱ{ F9X('R5åi;-o5C076 )WzƗ9žS(ڴ Ic}e_ -{O9]=IS6n]|Miz=^7>?"VvQZrK^u)QOջ0\$#vsB3%ubܖ{@DŽ=Uw[Yk4m tآK'<`ͱ[-I MZ*ʼ{uaKJ1'>bB͑YInQ[I~s+D&C S3 yKm/LvϢP4f\Oezr%d~UB/x!Tb&bZз9sq:|/z;6zՔZ|(]E-:nQEH|;6LNʀL&龻HbB.GgR)VlR=&M>=^hjS}qZ4UܓGSEYLM6+?@ ]p} N 1#3W?3x<]棖 #DNF"vB|uhy-kk5Zw4"\y;tx ~`hGXk#]u<zyF@';C>\ ~!c0l,#3L)8qhsk}B4S&olJѵcO R5sc|h?&εQ.8ZBPЩd͸,LFM^^Mn<5dg*l\a@+rtlk @Q6PCU=SaD~M G'r*-#rJ2l GgeF̒aťY(V9PX6=;.v<-ыUKp1B >*&1,e7DW!iަ%3! O? a'Լ|Un 04:TuJ#^5+MvqRqkdkEZx\C UhZ5ztZ>YOJ 1I<‹T CȧΊw`?*~^Ii@}3 -6y`(nN$wuMmp@}֤Ayh Rϙ9;s#7N uIUNJK^t r`>㴆{FNamHB[lTK8Zh3EA1:#=ʒaߛE=vSw.D-ފ{7N"fo몖cZJ zd\P1Z[OzD6SP_P.,eg R]CGى+SyvUwOSeNѬ(W{[:YCyyh2H9cҳ B _Hl0>r;E;yS1F3W !ՖOi#iА`[gy9}(zc2v]Ng#z?eМl,Zf\k2="ZwqQXmvoQcai q˓meG&f-IF6d.˚2=f{3n/ wO[UŷP w2 ʁ'X53ܕ) gm}܍P1TPz;mP*p)`{ʋcxtYfKe_}! 2wQȏH X˅~!Oi Ř>+:i:~ߓ7(JZl$s{?ʴqC%z \oOke%Ɂ20|!37'hٞ&z *ط YCHhKM^xX4uuцs ,{>Q[̸ǘ!٧,&50j=}'?re~P s.N6zc.\ [&#Rmi[5 f<6\_ij5:3eA@Ne+~6wcۯpDtP{)X u\S' C7hF\T8|\OD/MUIHld`^Hlc7g@@Rqar1q}M^gkĚ|gDO lӜ |C'Y1؄DКoPl".vVDȨe>1t>jf, y-NduQ\߈E>‰olv+ P߁O: q:>52ǩZ0EԄtj/6.R.L:~*; }ߩICI hDWvRٹ;QkS h-lo]B1ҳLfEg;w n+?q@!!PӧI-t- a@l:|}h^EhsSL/C2Mx!Ur} K 5ۙi ƛ 򔳍"k\ޗ0s~OP ;AܞHkf LZw>2th6W/{vVf!B3Rz6&f$ `r["g4:/vfrGtU̇ 0. ּ5! dצrqg[}[}gٛ4 ,ł, Y0 :o:do׋`[NWABn{!cnq~+@frdlISB`JZ[.~#4'$wUrk *s?i xܵFS;CE[c4劍ƨ{pOg70FM&W}l(j:M}sߓVd؃kBpiuR~lgcעp{6*FT*^.%U[/ݹ_ȷo|09N-VLnrTf|pDW6B8wMS(V:|ԭg"oϜt`DmqM!l{" Tl`Mt2oh\b &nR|grUX.(d C5N}}{P| )"aT8ѤnD:|KN.>|BO9صUs05[8x֙D&F ԿOid>s*M.!ĦJ\}G өX| Swg]`4h\5a)]*zSҋS%/g` bں/, |Xd5}4pxbİKL4EbSΗWlFf-Y}d/%3Ȯ'J~#M|oFuJ T YXUQQd x)s^C9$AT5hb<>'qLc/35Rs"4S3Hdbir$5]І뚮(3Q#W.O|2aJ` ?hbA߲/Y @ENO@ yԟYfi9 a01j3I+%QDb,2%r){P‘_L)⸬.,6c.Rj::r:49G) 1H5k$[hZra)NZbVWBLm1n!{ U֭lw_O/Ki:A#|/]&.R܌QoJ>wq!.m]`}$B)46cM1ԢeZ7 T wplŏC2` t^0ްz,eYr~QONL4t.*+?14*xK&BKx*ߚ6" %m!fN} 6ex{TLf_0D1wg)}%} oTB~]`w+7̀,%~a/_3B+κ-@FFRz*Ѣ@<ųif)]zҼR)=_7t[H D~"#1)ÊJ‹axOo+N/M(bzCWo?qTYYJ-)%uZJ #א9 T-:__|)Ń!a![acTuUNK;6Hii]6Y"zś5)1Iln,ҏCymN hO3Ojex’egt>e07HFo$A~ 7B?[7"O#Jr(-] "omr}Y\վ`6;^p/vO[ձxiPuR#LFRZ姮  0fRc,gZKǂC轜;3geN!Ϯp*RuYR*gRP jLD2u-oF:R_~Lk/7c-Fkl :Rµxoˁs2eM+ފJS1h\BM%W|R,j&L!RNe0/)?]䡖 s ,a)R/lCTovİ~x|u pŹ{dD~=UһQYSy4&'il,H4gN,{HRHRFm&$č\S:wNn.2֥>r2WgwC Q]}ZK0?NѸ2᫞eVU}r<8]T>c*gGkUFE}7Т@0^b#vY := ($S"j ھmFcjh)MZ4ij|MdlI?Ű(.}6(&M}k)B%ΩPjFL\&J/_ܬ6!VDtj?(柳ru%@lw@,a*!C gvפMMA*axfkl nG̈́E^h˄tReRD9/6 _v^v6V'+$EӉs:y~zmK9`o,Ox,yh9PLXٖ; fxkće{r%Ҭ4?l H9(D?nss W:&˅Gt9٭:Ϙ#h ]ѽkyȹ#mx# rk0pHUOV2$Hހbȋ/Jm#U:s ^Qm I CG8a#*ܴoXh=-hJMB~ԁѵȅql8nO4u`KX]6E0},pD;jd$H?sx_O2I_&Gc?\ ը]0 4nIu?_OtFX oe_9Ws )wɝ G1DXA rr‰:D:wEګEz,@'DR7zn8eh o?qT˴miu.S+|+^X=Y踅Reqo᭄^SHbEds=T[gqq|/=Ѕ8+25OzSSW c!U0a!֣x_){;iYe0rVwFBbž7ѥhsLn,;yɉY g9|9!nis_&3[NE |ڽ BA4~PZ0kOq&guX ly5iE`LyYgzէ[B%tπ4M>ox0UMRNJlr$Jp즞>ɲ8s(KzSL >j}"/_E\b_uxLQV1A1ltW؋f, #mfad&NJ$c=xX]v j/F!~f\鼬#SB'laW„bpV=hؑi/}0zZ,cYl-=gFffˠ*.J¾w3ؗO'-Wћ_Ae6g7ij5qJ&!"BぉSR`B UIhGd*O6D(Mb.YI-}MK^qIu!e7GQ4YD|s(cAgggiWmQ,*uWx04Y]%n+ 1CQ%G5$;|= +;Y*!~26`ſfK,>vl@xi'zXǏv{[nx<!%& M E<^|WP|h#YU|3pUTMj.gT!-nER %2ld9Mъi7ɾztm3JX=]W;5 ƪ[~4F97d@,Rc+0G@S-VOK;RSY e'IMަV.uod'Q5r iϰ¶14ZͰìO罭L !us'ĹƏ4-!^@9֜6^˔0rwλ#dq0 \O5NY"s>|bQ0rLIM$4¸`mK "׸*z&E@ >(SS0Sqё ]\ڬC&LE`–#투JUK="Ebin1!|q `N\5hڷz3p^I~)$tg`OGݎAϊ-Ƴ` {y.ize7zz鴀~c2pYmW%EP)`B8 L_өOr{U c&'d/Kr%#FmUpDLs.`+؃'RϾ-BlE-nE% 9* /m;Py{&_n?ou`QWLytCwf50ÿtuO@( [B08` =2[3.38<6.܋vRE++ASn)n=ڴ7L;?mg~5:rP*/A m?sF3[]@\} D?)ʵJ@]Z )g?K>ޓR3\JBG5 R+!.4"O8`][3_//eß ڌߴg=)X‰OC{^*;KlG7) eϤӜBGЅ'k| $XPTujoew?>T WOyBvjŌ>"RJL{)ZxA6DO8e >WI]I^sמSYp}e"{6}RwROxOOnʇ endstream endobj 55 0 obj << /Length1 2401 /Length2 16776 /Length3 0 /Length 18169 /Filter /FlateDecode >> stream xڌPw&8wwи6n!$w.#g2WuoQ_*¦@ {;gzf&23 BBr(h&3r~ȸY<̜ ggFF777#['{@M P0U<@/xX<\L [p/c >  `fi|cpvw03̍J.ddiGмuYThG~b [="L],]b́v&&&Nn6t7`^[>^">f?^NF@3o<33` 4&߆t03鏟>齭o?˨*)DWDD^lzvf7 __J,΍7=z2\ / o P|]&v&_Ok߄$\llTSQZxm.oW!ovvT%M-]lV:mi;Tm,퀊N5zf&{7mVoߐv& ;2gz[/vvہl# <=r8"Q`XR+Q7b0Fo, 7E7zcQXT#N? Fo#722=fοFt'acCbk;cc4| 8?ު6 @Y"Co[F{_o2g/VͿ[?lCZ3ڽoN?b~޾36濥 [oZ{_@.@?y!w'+⿑XW10uw+@@eVoפf/ M_-Mћ{ w/ߘƃ[{@xa ,K,}Zn@cXYb<7*UYq og(D?,ymS;'vlm=@'WS&Z~gWF>yʩ;d1l(Nk-dCtd}XzRs6d$~pO<1-%G >去?,%3=Qa@77=rWᚪ\LB8)ظf lM_ԡU_ UDPl1?˝Ųs7a)m!X /_#iŤ_T}'g~'!x#x#-P{uG*>qC<ݛFצLK^~~|0 ,ng9BB}!? ?pKZGN]"vU@-;FvQQ1:\+4Egf2H7uk(LxfRJ! ]iSqŸYFa{ĽKm3LkRb3Rb;^% ٢J *l%OK")vkK:AY MQYĞ4T^Aϔl4 #l09v9a2!fޓh2\?ҝNn艜|œEJ4/1h:.2\nwˍpbBUڽp}\Gh|۷fF ˓\* $,HkFp7C/~#3%ݎfgy <[(x'з']/C="L3H-'y .-CEr}SG[)F| '팲/\)3ү;$ʐR*`=`gjImcW*gX1>1`s&>5M%Bnɩk]v+[iНL{#I]\❑8GVj2QԂl{ѶTEOaT}#9؀`KbG r`~ GChHj=>lNgTF/%8^N٨ ;&H g-*gS\'4}BFI.75R]:,vc^v؁Ĺq(B*$60>MBm3[M8_Űޑn$L-E,l>kvޔr!)ƤfTU)vUs0jXK$'h׃!1*#H"qTuH)1 m) T;kwޝ\Bj"]&5 )Qn$Y͉v یMෲDLR۹u,E?zK|=o5 cL$_n#+"Fq{,0؆ x`Ĩa -Z),8?s&lidkM^gWo3yɕ}!Gh8i*ZjbהCNnp jp"w>%ҥ?m$p`]S}6ͺnhMD]]݇LC-^]XՉH+^0|XܩAa&ڶdaQ17|*S@+Ӑ{VO]֢f+)?8#ai?;1ܙ[h炈- &YyXW.W<( $HIΑj%琽pvxӅ잌]1&dRj08(sɿgҐSNe F\}\1S >Dc'ˡr}Ol>M)pPTtчͰTEx;Sh6$ OqW܍F?fS?on&il꡹YJW㹴._~6E$&nZ:8r4,a$O(R$E*MO>u 46ym*/Et:'>0#})2ݳjڹ^KJTLT{qϪy;0#Ñ8 DӀgbpic:D &G)ڄ1 3IZ>3-;KFvY e;8g ~ĵ=\8> 97ұbɉ#*ҋHHqG 67I`v t'b *[X &CGdRj`y,Uì"#o42i 0'-x$p0"-¨Քܬ]fK "*ƶü~·HL|'J> Xf@եʿ!_>D禄@4q4+u5#u"!: qu?*Kp^$Xi$c+Vp68"}oLg!]%Ï;A5t"N_oUqgT 8r(G$󶯰6j/E?#s+Qx5cp(Kލ6nP>bU+[Ġ6p \J.ɤdؖpLu $UfMYg幕NI_*YS%lےy 5qiv<<@ XE9y,>hUd/+ 9{ ^EP t(a>{[gXY]p>ϯ,17VPOUp*ʺMZPu n 8?E<0*|7]N8([8ILf^ˉDpI1A*nRv>buLgOn~1v4sS{K!j&*|jfbU]|xg/pwĈs,D1|K +=[6RDNY}N@q(;Bf2ژڮ29'Z[e_[k3RQ!P$$nUm8}AȒ\KN @%z/HئBG4z=:!d R>@ {_e4uQB^3QM1LlfqzJ?^f8dwZsqxsT4T [#z%K@m+AA; %3=~ Z[ W^$#t{vX`[窸K!YwKL"s_\Y5nbNN#OPTWk LʣRh%g<xCK2,OWsCB=ѓ!=chڠy֎%݉_0$kױ׶meTu:a Vϩ@_W'rN g?P*Ҭ^Odhv4Bsռ裛JgE"9ѡiFǽ"L?CmLC2^{+?5Fl r?y^k\ul;V^alQ%5,G9ܘk`Ɖi`gK"C"hKK[k\ǩv*)Xy0s;(iAVS/̸I%=U4m H#$k; Ynj_11cH %uoJo@4#@)o_g͟^?[?8}ʷhJ7 I1)SPm@o԰I H ox,H(쉴p$%Gx6UD|/I~q`mcw̔YT0(TI--ARix1̒9RZ('_&f+FTa*zD:BrsM`,2m_ Z'dZgP8S7C8D`n%Df,hWW?a/uvA4Q p/8&Κ2Γ0 B`pⷉ: (ys bD{G$X$GQ Բ;OXstAtl BXY" ?tHZ:o* _ТS".'HJnAphV1n@3j C+$$xCa㻆8; P9k۟vsc-įP\^. C`&Yi=ܕR\,#ShWWK~ 7A *0t8B( 3zY[y E+XF}?:l6b`EA/,OIrfsEĮ{i.D7}Z5\X:>+/+ɳ芏HkԺ="mft?Tˬ15vh5M)G.g%TWMxfS#&4D>R7ڔ;o.X59|·a+6Y5\d7LJ@m\$;gcμ\'Fj"$mFE0cyic؍e'Oua| 伢Wf]R_b͉rc.PHaʴuҰժ2( .B/w3n@>r=F[ fd5EͩaQmU .HSeup'k|}l{3Lu[Є\tGBRG}DdQx# u/᎕!!뇻4|J>a֣ qىT {9$CeZ)*",4((xdnk+y;Xu?uKu~V˺!ucj_jހK f_)IҮu/Ծh,HXpڽNh2?!/Gˋk,*cG-W64y|2ɫx|?#u^mwݘxh'8@/K0IE 5<*0ޮm|™gd"p珢QZ!e(/ߵ1$poa/QBTOv )c$׀!A%HSt8]yT־xVj7&K0øD0 bG25U}cMk3(BIR4ҲkT4&;;ְS-iyat4nh@2wK94 B!Ko ?%8 <^;ޟ:Y;XX 'gf7i&i3ӑj z[s"[i#F^* 9!)+!TQE-ڣ>GҼ!VLJwV){(O 1u c:)Q=sr)@Hge]^ΦBi 8/ $p`~oW }L:n6[kLO0hgN v~eh;\IpH-ƒ)OcV* 2D^#jyNM䁇2k.vmaA f-".s|KF<~upWY}?S(7̊)> ɋ^nl=`?̀GkCD͇  q?GZ h^ 5uv0 tt@zC}q7"1l滲mRL43Jl c8OD@[6ҢCy+>K%B#|)SXf%^(Yw&[hK95BT`wʴ#7ό f*jnS]`VvD%z-c良ic xcrEUܟ=w!\k`-Ⱥ8&$DVPJ2y$˴b6P%&_Y҉m`OJCavRD(g@@(9 W1=a&e8)H n6k4 2}YS0es pJ| >iDveڵl#C(>n tOOMqⵏ`A}dJZfH[n;P גJso&WiZAs]ED{g()蜅 q"}%͜^_.d8A"r5A"կII nR i*=ڄR3ىR;w?BPSl!g=H\\WKL^b)1|OшHk$ W9UﲟA a&8_.(Tăo{䰸نJ٥ {~Dn:ܔ +zϱg(ʠ!o4Yhw4AY:mYoF(sOK|W}F:>k.;e5`3TR)m~CXu98|^$#4sp#ByST=%ͱ12Y,ڻL<\ܭpӰf&Jri2%ax>CyIMkn _U]X<|6,`Nx v9XdYr@VgsA3o]+J;@A9 ;c툨]BX~UQ^twc'WV!cȿ+V/}y2۪syWKTW%۵g/sVn7**e .I?eΪ? TC7o{\>Z"[kz4?J86# =' `'Hz_@ F&8C&3&2-2ӔďJ&:)K,:`dJ t_r 7i:JDLKzRIyE}2[1Qg URaȄ[൳]4 -A}L#uqcet2#RI[7e~[yWz'W<[Bm6F3pm*l0HT3cHߓHY)֤aP땴Ph Ff 03ټ۶aG5p??n@Tط=g5{c[r`.Q`$9<8 YJ{Ƀ")"Ko兏ᤇ3-~8J>ˠK]ԣyLidj9o%_q-Inj ֠t3ҟc/4 PҬjDΊSpAORM0w8ȏ`(ʠAmbc=pбc}k:ҡ#AK5X2Z-ϒudVôOxrQ)2Dy!kYx {Xi%ńJHg S2^bQnēI)xTh*icS>ԭְZ. (NT8ؚ,wt=n_oF̺r}䍫+cNWhmp=bHGi4܎*F~(nB׹C[)sҟ`DW f-TZXoyAqfl+лkh1GFAOtO]T_){.a@Vt -x[B!5y[Ej18z*mV 9VGkƢqErmOk̭$˄WAk>=jm;br2؄1 /Ȧkh$ge3WMî'ةbY:aoؤxJ,h%匂4DI̟fRpD^7d5w~dy_Z0?+XhD#St.*/D [ƛC!S.YX& cy}*$ۻf υ ۚ=kT8ob2>F$"IK ݜ  jǔM411=FIW4 Dന@O!Ƹ.d+nU2g~4$(=stoecMÐeߋ(11m›L5CC0+ԟ|e U<.26+MFח?}8rCyy+P`B;oT.Hܳ@S(+[2j >IL )`dV6N5Ya*0ވSH~pjNH0]Bo8DZӰWh$*8Ƅ穑) X`eROv ־}u+q#$3yylYS@I擭1,gJCU9A:RQ=apMq(ZeخTDr,;,$ dPDMYkBbBI_M`\ rg/1La_Wc`t I͕wƞ*ZyED$AsccG|qQ[B Ѓۿ@x2TbYx#-!ԡƣ" Q+!-#7-8F@vMRd:tu3)~Ѵ9AS6Au}C$"3#w V< 5[Z ec[Mږ0~,e ix pe6]ittЃ;*ZƲrj{] #7`"rrYl)š:gZdA%ȇ  @[y`e!Rϕ?vHֺ%Y N*IWl}lT-d-uyIBygb I7yu :\-0D(R,FZe"R+ $D${B>Yp"6}<\ommP}PLPͻ(s5E;^Ac>@H6>0,xm(PcYc=3|CM(t>^pm/k>F*Bp>eײ+Q~q1c@w!*RgBϛi`@1NX:O6YY5*Bdaus ϞbL\\X]|ϒ5.OY&š ^nQ)R{ [!C8:xR5d1 R:ˡAq6`Xn~òlKz){3@"uK7I/dǝnCN@%38ۓh a Df.2݈dsE.AJad;??OMD:-*h7Z"^8iMu[0pXWe}3m+ ၷAqYqT}OúoLk%tJIUd<&B=U}mE/%E}c4[v p ǃsH@,$&av+qdeSp"JŁ4W2Ym}ݰfgPuxS0Ԡes?%4U# .t9"L>[)xpHz%R Wh.]fqtS>5!ޒF/4Ji3tD ۟RйbzeF%b(eðs!dvz7bg* Oi6sXRPQ% jCO9nvYzpvͲ(3-iin 1[.q?>&K}sfNv2}rR[oWCfRl1Q>X>4{}<>4 ?zglp h(?0.HO- ]J`yV90_+҄zJXy!:4RBbf_Or:Rd'.YC?-wy2r̙8pݿUvߣ/|iOa`F̚GLE%z4ξ$zb|;eMkZmUeB63ij,TFgs 4ibVb=-c% wkxpê򚎵=N= C1-G=0aI#ӟH^1BJOU[oV1jkbG޽'{0]>ͯ5 ""}r]I*j6|^S7g?]1>1lHM| (Qb6Z(agQ :35,vȘ!~:c옚rzM Eɧ^f*=噿ڡZ{G#&gXxvhzCGiWZqݢ~ATI&vXA7VAR) d@2TnQǬjg^z+ ښu`v>3'@*l-]r0곺C0ϛ_W\CK̒*x/(*.KAĄ{ʡr?;ݛ 3 vtWw)ƹ}/or AKⲸyB"XˀJ 6}=ll=rdF$U-W~a'T1S?۲R+*/B>aAD2f廼"hcgN/z4D`ىʗ٥@$1z~riw8ʼP~9(-"&ŋe0~'5F#{c?ͿcTCFu#HVGjA w! WH]>alP |HD:Te WM.![C-6]4Տr1so#T *@Mѯۓ̋e-Dq"[NW} yul/nӝx&_ c"ӭe$(A3NfB5jq0wJ^)gsQgR0W0?vy9^OK;s kӱ|.Nz'I;k”\y ăM0 P~Cj9%,.~q dk|b6Wz>AnsQ$:)LJG8˭JO[=(wDι4t6&'TbNpɮx;`=冰=1)[-@k7,!&#tc&S*=M5p/mQۮ6EfԉKl={ɉ{51UN6eO >@a:o!o5(FIZNTP w:K?3Nf-S#O~v;77Lr,GHsulslMHpƆD7R"݉F 1ʤJIh氦1u]~^FXF"CC> .awT*a1Nph: ynpCsg3:*?posjY1<j~pdgp 7/6 D+z3xlbN}cnF 쩠ֶ,̗@or5r5U;owϸ7$*`$b[pOTeXU'Yu֡.}<?]b&M ny/M2mڳd9sTO* 'K/N'gMT@s2GNJˡB0xHB-FТ''!.K/uSZ~frF]MSH@{Lj]@jGB.`2G.C1VgJNiXz=J=ŶxeO9}BZY+d섣ЊMJi ꡪ2ha4$}$(Ԁ,&@ExJ :BUicX`lph}4N!h代HX Z%q II>مΒ"?&5ESV\i7lQ P7/>x M0.ϑН!{-uA@`qW&UBUor@DDrhHC})ʟ aUe9&.\}S܅gBʌ R+~9´=bӐ["lb 24]Xdʸďbo# A M.b|C5&d0Hm3J e"?@ş&|B*BK`ی'vj{UKLۢ{R؁%INEX endstream endobj 57 0 obj << /Length1 1562 /Length2 8338 /Length3 0 /Length 9360 /Filter /FlateDecode >> stream xڍP\-JCpKcwwm-8,. !hp${ϽWWSZc9W55AX98*n6.4::m#o3. #@ddp{SANn''C_0!PAAht0'o20X18Y$! bfO'f?? BX<]ZJn# d8뼪$dݙdd]trDNcyr!{yK\bg[#rdk[;dͩC?%QX%;;=QwvT/Ļj:1O b5^'8t2wɍ kb#b23~O(!_ǼEt~ GB9vJ7~ 7mhR?Y=6s?P*&[aqt$tGc5̫HgqZ(>-v $ec>#&TU=k%[yʯbxaLHUDԛ?4ܭ uDžh7QZ}ҶA"a!Sa+z` #Պ{}bbI1D.(1lfLoЫFLn&kk{Χhuۺ7CK^ZYgI6m̜MwD67\`8NӾ ZM|;~Rsm #SnBY 2xl<~_:7FnS5"G A|;VX+,qE5фFQTO yl.վHsYkؘBW9Ud쳛 CD^ ! ,ѣCVE䧴<)PM Tޤp#}tiIPsŦٗ99ɮCL䢒iezC[AnTf'FXy+JpHWYԼf"[Η3ݣZ>hhӟ+%:a̧M:.'IU=RoCsz֝qUKXa9U?PǕ)Ԓ_\j/W%/? 0PΪDoX Г"a.;MU%+V"'WGMJ3',.5ȋcE t(.Z.4z8 8h0%3tEr UY-: B+vc8ݑyQF#/4mqE~qŁ8afL_ĔKٳ}nH!^cgp/QH5XVW`ݳVѮwv Ep~/xq?W'Ɗ>]乷OjNgK׽#)1ci_̻@M ށNmw-͌q3JUѫTn 9]J ge`bTX4*uldZ;|cB⨡7tbqo9sOo`Jv+Yo!NsgCIU8AE/$y'UWtVH}-^̕xv xlYœ`*Ĺ8 Fnoٮ91iQI=oBDUܫE˫׎[=b/R#:+{o씲v_0(Ufe+&xa;>]ReԧnԤU:{dTs{S4@ȵ& LY`͆q['t ԓ{J;CgKa&ptD;Ahby80T#ɛ,>3.Q=WJ~гv/VѬ [zEI4~-pEi~P[aԦ.cN6ψ: д;[/ckQc[7U-'ތM؄L/čm{>K "qk2^ЭkUב,N71m&iPaM&ಠFF&nΔ` Yͼ|܏GV3Sbm(1sHc3`'?H~$Q(8>SNLU'R]7`0ݛm9 n R:g)|pH"[d(\_'49Zl!AD-!}{oQ/ sFU*=XLk@%Ӭ-⍺/+匨sǥi{ ʐ*4KpRy#V+O{m&[ϲd":Pf /إ/qir`xM5ξ,+yEu2=h;z mcw^.Zz Sqy+ -cic b^]wor݇/5l= ?5y@P51k`L*ꁑ!0YOWLڷo43*+ĺk~~39R\WHo%Nnl4qm-1Ïd\1)n$cj2?z:zYZj EQl`.Meahv`WbVJo]w%]DDEy )95{k2d;ྖJM \՚u$qGas_f7¦7(6Pږ!P2?Ǡr2bAS c!$59:>В \ HksH-1޼SKm٣(37pq3g ޅxҔho7ӽEF < _˪#Gx@&ǩ{vgf})gUDLkf -(B37eSHMm/dc""C*~l,bJcJc~Y p,JhcqPэCV ftyzHfo6@x:r:(Mܰp?'~M?М(k+DOf[i: Gw赶UĚ?(z2mKni41+㰬c7wTG[Dp (d EsLo4ٜW[6`l|E ϫ¬Mx)=Btt+8Qڊb=jIEvvWb@ϳ, ͏ GĂ ފnk]VҗLg)su3'(gvۤtjnI(Ě_MddH<ƚ*4Et4?cQT;>)*`HҞm:|knZJmDŽRhS %:ȾFec?'&膎Bbc[>>ڣAS/%#Ze8hdQ{dM0pi.6L˯K&J 15^j6#C;߮cןp|UWY F$*;p̼; 6H5iւ΢Eg"'UhMfy:LS3i8(JY(Mjpd;/h$ c]XxI;*ѕr,ut'ugFE[%&WbvcwSd|gE܌ttmuR'V7}kv4_AOd둁R7T.D[8X`1*fJ;g9'J;jh2y0\RZڭd*1 }ӍPTF]ѓ+x=Y\< ^:s3˭2HdeҚdqj˓iV)`M8ZSe( 1[˭B2du3MAmRɥA|I]#j5Pwb됛j`sϛu ]K2aM,7 Ǹ>krN@VuNEzl9Fj0/&֠'Krհa]k-,XS 㹄b jԗ`vh"ߔ9֦v(gd]EʎP̤d@p'b {#زKp= E[͞HX:L)jXL2epr8ni y'2;`1>N%YZϒ É1?JM~qa.ʵ 7B(F_|x0xbsßwF݆ׄ(Wh:hmJɬ&x%u"w Yr'yKnx3Gii˚_2?;%I #Hri‡qԯ￴W0"NR^&qpuĉW14-VDY^dqJZ&gE9&tg:2ez˔'[vg&ck\Hr,Ք fNkζ?15+)T%2rjZ`|;cHBT3ZQ<+4nq?Uf=|AۨUP\MWҵ{T`Wj $]ΧV/{F&[?6X_${WrIEuS<ÈgϋSuO (:@ߺ2j_}q\F2ٺKtd'ϯP%-|s,%%dC,SCUUHWRF+%sG9'c endstream endobj 59 0 obj << /Length1 1395 /Length2 6090 /Length3 0 /Length 7032 /Filter /FlateDecode >> stream xڍVT컧$F42 tl1r4J  Ҋ( RJJ()W{νgl}~{TT D1PDK~~3FQrͮCx:w3@>@"-`_hPpu(7_ AbU:`@p A( G+ @S4 ++)Abhu_\! L 4sEx6E;c8@(o| kMu s^G`,a_<῍_j|8O'p8o/qo 0,@ɎWÝ wxA_Oxn9Q.HJK\7Mh NT\(*.B @!YZ#(dA9@_0|"wC4p?Ka/C7?meV(b,~# @%6;!|iB񛡂rޚ s@( ~`?&8~]RC;9q)i KR@Np߼Ph,> tFc)) _2-/o"Kp?@nu{ua (E(n sLC&";bsAiIC`_y ,1Ÿ$>dd 09vJu7JЙWpwV]|R/(+g"DR+P-W9C+ӧ2j]^ ʮ={sڗ[q[k-jۘZuH3yC(q_ *=&ŨH]xJ"kWQsDdg6®AbF8ݵlZ' "k")+Jaޟ𤠔-bRsRs3rS$wĥ9l&X?K=0eLPJ! }I]vA$o%|؎ >l2EkO>bw8̈r)dR'=m{|C[VMF |[H>IP{tϩ|ԝ&%2T٬M|$rJ;F s!-dXFu9NׂGCg]\h[-j2v}ÿ{CyL6kiW骹rtIh Y&0{6# ҷvifB5^L0wXYu\'cӠzH%%MuRFP'~fz'>t|Dn797]b4I:֙#@_㌠ԛ4B(zYs:I!l~W ]˹iYBuSqEiuԽ~v_S&&}SF$ED #ߌ6+Lb62ի^O*8ɫEJ56|2 $o*3#Ƅ8aC㳚nš yu=:'gj<ޞ<NXAtڭrHr8ž^_x9ӵ-yQ$7IT. >6 dWʞ?O}V mA=xAʧ<E7hWtuƸ5Ӭ4tHex|"\dn:EZ9~NܦΩSX>`">6E9#aIr<ŏ;4Zm {d_= Fx@NCx޵)msFi4ANvbkmۘؗi_*h%ku+alJi :Y?uf cT`39y}YW_?|W: U͸$,T ʮ?,pjUDOXt=0]P"a8":#Ȱ殪MyHF^0\?ד)~Hkr5$U>YH'i:2 ::7J_Q*y 윪G"M 1, $[܊cV5wfeF X#z=Ghls}Ix ĕC3^ԙ?KŽgj6oSچ'8wV9R1&sjk#dY) ? 8[t1s 7dc*DM]%?]rkJ:U+V& =mwЉNwEyZ)&/8m.®d4.q(zn^WY)5Jt'\ZxV{y#[E\MHiM;I }žO$䧗F~?a&}d^2^0'<휘hlN~-Ez xOHb,9}'[/Cvs^\ /jBl0V6c v,mFN:`r9 ^gC-86XNI3=k*bWEa2+=25k{L~\hbQ7zW(6>z~L )@y.qO"? cż[}6hހ`y.&2%ћ7jNJ[iӥ&iNu폥dܪQ֜!Fɯi4-Y KTi>0NcqDUϊۘȃ͸W&J_?k{]Vty2zfv !>mF9z}7w%ikU_DhEHI~a7<ӞJ@] *g$c'Ad籨k|YՔ+L6mî- {&ϗ>3-$j AfQafQ ݋Z xtHpgg~AIRvM;;-Syq߶ G눱SVmw3 uj#}Z5gm>5kWpdյUUj{@ pL׊Oc62hT ۵۷Biwt]iiOF+ uXhl$lai7%1؅Gy) ) WI|\@2EIp>d^j\Ml+8\^, 5_Ϳ5tPO! ιh37<#D}is§@O ϖEBfi FM2qpw'{ep\#pZ`G@T"0+'c3 Mɔ(g藥XvTr9 ا$Y-% f~Ga?@CT a(p).qGq%4#[ 3kE6aWكTӄ|WPr=EJp ~ZV XKAֆM=?ׯQhUJi49~RrH Ƙq٧ d8QR%=3=rU@Yֳy#IT:|Յ]تS0nv3!5nMN:[- eǠ{JsTi+.cRH"۬lFE}gZS}ĻSm)7QzsBL 0Y۬ngwX`mnjӍt`XnYWyRW+nXpIj9K 1fr.sT#ȪSJ$ (ie ǖDG69K*YYm_lF-ENCZPuj&ltW[@&uVXZ/c#"*¸|#8r {ւmߒE7;,oTw;㨊rQW^YPT?@4'AfTW>bΎxcUv\pmehTH<>ْdk#fVC =gqI[?֦ѝvcw%rm.RAF"Y;Yo $:A󰯒Sz/C)$Uٕ j7n{7zg+ؑO1EO2I2s?/Pzʷv-i)0M C)L7nZ]e2e =՗W_}C,n%(& 6Լ7-;LHCTA>gdg&%ed?xnB`w%tZ3u?%0LS=ɷ٘~7FsGQ v{ wmUh:n00& Ln_љyAPuٗBtjp:V$,e3V,mWH]6>{goϹ$5BVFw"-HT]W;-!w?x.}Yl&{}=Z K.9҉\B {>gkrQv6̛wrp鮉d`-}\\d4JJśv3ѱ?&pxK3ܚ$x o>[j^ F)pw ;~Y !;\w_%. HHF3zT)LE&Qvq-.a@Gͭdm$%:2O;__*m'?oCamޢ#gy߄1LŹ e.SP \<\s-34Zu:>cra6S +/l5zX8@ _å|6Y$"AL*yoRZv} n-Q`~mԓҗT*!4_iA.^ʜ ڰ[o j}I\TĮʾ UdBǑv/{"G 'ϧ}ynxFeb| ^k)Whu([/&\ޛ"hvp6&UpEܹ!~|l֔m3BwX0RTѷ'vY1x䷋F@LRb޺P,ұh CDF&||Cg;_ #a endstream endobj 61 0 obj << /Length1 1395 /Length2 6088 /Length3 0 /Length 7038 /Filter /FlateDecode >> stream xڍT4헎^h`{o;A`-jtA-zDE"$D|m9g{}ܗ_nQÐB i 98LHwZB3 I7 Fu`$MhDBB @}]&P{ .Ht7@HJJw8@:a]0vdRe]HOiAA???,"]Fo&@0qz6;!p:@`#@k=!?upy5!+;0gW@#`/G7ChߍJ0ߟPO7B_iЗsT{x@`Ho_B  9:)h z@4U@9C1$!% x .xB~~y=NhG HH7["8B{3FOv􇌞<'}Fsspt-Ռyۤ H@!8@}w 7?5aNpw ?9s]GC 1#&~}[ iG]8z/`jcu!Pj"P9}Pou?tp@ 69o~ UwI5 8=x$B/#708@ 8)*D?VetAB>z~_M@! 2Q QuJ ~[r[O>?H2ks#ߔ2{ɖ7Հ(E&G /ڦMnοy;Q8Do|lՆѥQ#Ibܯ_ÿqbi4Öv6ϊ)$e3EytlH~&|cԷiT^$ u*antLX(I ϙZsA%odKX ne- |Ω%Z}G}*Dq1^O]n@q0}~㤼ͬ5qQj0+^;?olt7HQAߗԧ4N?i4ۮ'9/[̿ ]ffDh͔$*-_hzݒ*>Qy1D%+&>Sq5n M`6j6דe:z";uv--sJ] omY|Bc%u!,*¼AH4\.Ǹqԩ8&QoIɈ7rq./c2>c3mGw[Ny {̓%G(WϕܷZEYG43< []>wvЫkf Lj0$EcUN Yjq;j[buS}Eˊ rFp :Tq_&gr`n_Y<\y!~nb[]{rϬ _y|KlGA@d`Wmu&u׹iXmeQ,K@fq<:le N:KMWv wC)=X? `E'd^/mB}Yi-ci٬GcixyM8;W}3kpX4V %& }4WuBjFsl^KλXAC=|FS˵g=F| &<՝lCcܤbLI-u W6Ҋ=x@J1*st(lϴ毒0ܓBz=jYm{Y]xg=/m/xبxN6eSZSi=/tTq6Lm*tNo㺝[޿ؽxVUpГR0z?uJ& 4d gd37u'*|-8Ybog+Nr@>= ْ$b0߬j_S6ՙ,{m._A1Zxخɫdۜ\,s%I6rW ulByYf!ʒOʞFH9;;=GBodTq^Q*XbEaJN0']&ړ*t݇P̈́0}閏{Ҍ5׹)ayH7|Z _g`I g9H/#sOy_]Bx÷tyJNy23QҦ#]Ȗ C1K\ kEBe`Y6!2ᷦ9 {4k~߾SȲVʷ;Һ xvQbTON5MN7^\vTNüXİ 'hh! H2 NHPk~HxF^F4%r=)6ϦoinM#)cF`@\{9a%V VVwaQB>,gO @T><Cƺ!TgiJ.t+Pӣ9흏kX7 W;`4EG TAh(JFk:+Te}xeg QK 6ǏѠ ~u}zI "#3=x1mI)z㣽#@&ëPjγ)n;Бk9;1#ʭ6?~@H.}^ \!͢J$SZ8J}G4b+}],f?\5oܦN"B5=]xׂlqx=\c3m|zGF0]e9Qw?ws@QKd;+~m$Rx~wĞy3n4{ys%Ƭq PZ9{#;<,roL#D#NcdK{S9. ł(yؼ6OSmV@P0CLoƱLt3bue;ktպҰ7K^P譭" ;:B[-ȸ#X1~`a7#` 4;!WȻ=Ez5F>Dm9*8$Dkٟa-g@ys MuG=j8 ј!oՊgǴB߫G^e4h3e bI$Yӌ#fJǯ xR5qe.A;InR:B5@C:Իgsu"{|ZGl_&fvU֜㊆0CH9tw߹opY7k׃'D]!w͗x_}WtwU>eM GZ"$3s-,eM/枌^m"ZluxWno6z/ tKL:S?pW1S!u"m~&q.'EkuW۽H0.ǩi#FzH _Du6Pg}R {֍ṃrK_YjljE?%lIpM7Hx2?"45߽r,%ʰ\+:'|45u6dmNd+p$1x'JerQAO+[8Γ.i/z`k{N +:HH_U{Y}SZlg;_ʝcb~]XJ;*C1@;'Ɵg [H?Lcs}(&6ȳr?}"ƹ}]\] .x2X<~6eTDc>qۛ$! OΛ9'wEqHܢݎ}bLAkmVMV̤90lzjEhLsd'KX썉pAv]d̙uŷ-.A I&r䔔ڹ1Ԁ'i8xc/3~m*g-5&G/S5Ǵe FVz|~uk\*X:zS_̶qRV0V.늲2^ e_D#Sx_4^{ oCb:ʚwbC|đ B5&2XV0$1iTXp+C;`kqm|v7YfbDE!3]LDb-|<GDg:|]kxHS4nlkQ*$x7CU{'uWLyk,IkX7%-V;Z#Et4Wg_j_Hoc23u٘%.[f{Z2U"d^ ^%9KV.[]RV.dZ1))Т\Q9~k`ҩo1R)` >q(y#Y*ωѭ.k(dm򣷜*vוzg$WDʼ]I8bVdZ[>'Yt/re"Mz9.v0w7zp{S6R6 !W0`i,ܹ_盺 > k?-N^O)"3!qW~{+.Yҡ7v[,A1od@FZ]i|<1j ?c %JXT{VƗ$,t&C"w>Ђa(8_BX-b=[nG-Hlodk u/DDtDQ|m BJirۭ9뱛%c xx* #wncM ^o:Ne(ȡȦh ɪSKQ՘0VԓVyėC:5-*9#ΦLη^RIE%h2k Tlv Y5;)hi r뎟o%Z6p^}lJS<+3En>[*yF _*K) [I`Jȉ f>a|vA}jJ"Q|)85;^gzw+p~t?){YvxtmO?B}9k4NĭQil(&8ZMc=z6 O-}؜4CM}}u^Y&A'ՠ - 8FVI}edhҥbl}鼆OzmiR) I/(մOm¦eoi˫@ߗYsD0=d`זH`ɛy55MX)G~1Ҧa3Qजyn&J:#{eGdiVҾ"-y"-zٚzA̡^L9QLVKF"?y">R'PCY} -ӋPe`aqN|Bq#/6 A=-ϋ+0XN^yʂ 'ybFܓԓT֒2(#3]8]rפ~5;v߾Fvѝ ֔r' FyaV0bz}xIn;=1{1#UuKNxx\ׯsa9g#qyh9I;SOZwٛ>[-\ҜR:SV`ӄjIMxU'uL[3dr/>JLq4ds|L!a3Ϫ&rmvS(ж,%dbiC滼9iTJM]Q oY Aג|%̃*_Hb_xD9hZt1 V&ʖߍpM"*uW36qNJt(K?Zî>抋u~5q7ü{ly'wo|̳ ^lvN۩V{̼P|y\r$rX+R\Zcͪ q Lp={酝Gҏa_7sXO1FsCy-n`0 6@O6 i3`•:dg{Lk{ѻQ.MssQS\JݱhX0 s+ㄥAG-Ξ۞"i$vc9כpi|fiV mYȚH\yP\h \v0^Eo; 㡗[u)TJBi^s}0^TbUrgӸ7F}\d& qSΌёYͼ,S OJT{ endstream endobj 63 0 obj << /Length1 2296 /Length2 14633 /Length3 0 /Length 15989 /Filter /FlateDecode >> stream xڍeT[.ww;{pwww)R8wRsLqWJP*29]YXrjj,v&6xJJ5+W[<_2@cWM$*`uXXXXl,,tpH[@xJqG/g+ KW>hLi DVycWKȣ-@ ?&h,]]=<<\-hV h6@OrL5K+T]=hRr7:@2rEG#<V&ې_Ʀv^Vs+[ @QJӕ`lo[onlekl+xc2:[90XΒP%.㓰r*Om<}`s+{3ߩ92[9e$,NPcN%o'j^ɠ<|T~V@;7<++`cDBV?O93s#W4de%I'bpr?%oQ_eTfx=k pXw/ma lmGo`D*&?-4r2Ơe <#/V.RV@3%+WS˿y*9X>@F6hMm@GԴX@ЂWI{Sߛ0vv6g''f@Ͽd R2;8n-'Y7? ,q ^?4Yb0A rȦ`V@A< *Ȧ`V@9A  ^2Hall 7?32(Z2,ffH~#'7\fPl H K 4D@qX %ѬA_T?!r2="+^UbٰW'F Ћ_lP^ 74os̎>9;f׊o+_AReT,ۿ P<5B$<A{gMݜAuvA_+//:Zׇv׊x0Oq߽pق2A*ڔpJ(Y UBC'Hq{u2cCHG15(!dOt,5(}AZyM)$>@tsxM@\YNh12HupD췦jY__:эŐ8û4!.hA $:dײd?932v{47TBj|V&NQChj.o1#RGwwH ל4'oVFPb d("ė4,D[l ടR\d5*΁ !%z>Od}^R`m5Lݥ^.Z3uSuP0%?JT}6@>Ů,ﵝB0UTz orN)2*Qם>5 ā9ipV q(jӌ*xzჇY(Uj*%]L=|cT )-eS&rl_Uȋ)*X$L`f1N|Ik<2I:CJHRF6 #(OGyLb01ndʼnH֯AUʬ_ȺZN\+4r6Ay+* !K5Z0G鵢42օ[Jq7j@9!f(ߢ*5}I?EM`3}Y.#vO;:baP)g j [{UrgM㟋6-SHr# 8~'㾙ْϭjJcltYgsX&SƯ /*H5 x QEX"%Iïf<{d8KMWzL>@y+ap Eօ1Ώ2P|ȮfL)^M[h*`{.O66~-ym uu4z> !뼌rE (ūRMhT1AcS=_ựd oyXV;_*h})_R$˛ɍ"Kݔfvd«ΰ$DݭX ri@Ȼvܱ@;\pE>We>9E.jDr U sqazTDN1Rp&G9q@r(ɰ8\d}\U2 oSBL("hFMFbBsYfW̺7Sj~/z g/]4RmFdoUQ^K[ YU; k̮ HgCGx{ f]KkɆe-,Fo6-4we󎉊Uh`͒#B&MQy^2@?iÖ^,?TG`IkdB"l˄n#Wz[ mܙ4c-]]H 2}!De'P=.1[IeVԛuĽ)D4YH+{JY&*l=-p$y h̸ֿ*QvgL]2!,ظٹ5ٓ 2Y,Gΐ% +8R&t`ږ`i$4]L3qn' nמ;Ug܄5Ŝެ MHLV V]+F>Sȫ]+Qk4b}q؇ D l5d=^ XlZ(39i=y^tP{on2B-d-f`tFuǂk5Y~C)1i \7׼~ĹH!:8j{p.oup_n74XK{Q$"=1CM>Kfrlj \~۲u]kpVLiL0t|5 fHDA)1cWX1al`$v g]C/@}ز %eB(E;ׇwvH*YA9)p=⹿*Šfdɵy6""&>fxv# &!\xdAqw՝SlQѯ?΅I~r匋JzqFp)x'f5QC#5uŽP:=4'҉Qα.X=ߙxU彖V2T2걙m_ydnrC%0>6qcy.]%]?YFpe<74O :~)^#LHgG^qm_'ˏúY_2%K4 3 *Fx+n/(n`d$+4[oXniKGܶU[D[.]wB-8$o~ Z.NvGutD?qB$H/gkˮnLGY=M؛D,7&X#[CCӂ!:d;/.EL䳭Q=:uy%GμiR>WSʘЁ*euaхgz ^e۴0jXV+> PHy`AW yc5/]d|4a{ֳ.p3JF;o~cUQMdnj=eX-~W~f}V퓥PP( A}?TYsm\Ѱ`w͂G Sa,..}vTT`3 'tѝ甿5'8yrM ք_O9g*fgNj+OQO/lW07\eF3O>25c?)uyl/e礿~-d;R\e3FiEasl.M /_V6Sa}3BXtO% c!Z܈ R:AfPtZ 5DRqyo_;3Sr^@ (pْ [#my= Cjt`/ #~#ؾuFA!p*x;RPkD:k#T^9 lt!z JgŸH7d1d[8ZUDٶ広 $sڋMmwz9擮g]?A&HnҀn* c~qXc EV-Mc>W~{c'5=*"8Bkig#;󝸠  ɟ^rx=FIP5.4_- {?`|uT6V1|v:#o\6Dsm)X\ :s"pܓ7,rcx1ZU J{Y68EğP_Mʮէv%ׇG*q`-a5`$}0hGI}<2D`B02xf57 (.W#>ZMP&ASs##9y ՃUlR~5ә^jpeD~͙r5U9iBڜ]Z'0WL|/0WŘpC#%p(B Hת{ .ӏpO⿪V!!V%Շ~I*T?;qU~P5R1+un" c/a~U{fu:3iMpiWS *o7/z!2^Lͬwv6v<)Ҫuv_C׆@_[0I j^T_J%1Ֆ@l̝ ^^0Y{/yT&`ԖҠ;ݠnEVe(} G%K fbus!/X[d9rgOn 먅@HeFrRM9RO-! ZUV4?y]*&Kuz?WJňUQy=Ҍ`…[W+4n6E/\Aa|d9ⷹB{&"@uekqCeLJ?A>NQKJV;1pF(Mx6yxO.}QI.29`e4?YP8=GM} U _o4.`>1|Q(! YnZ9W/u}^ ð.%d7/WKĪP7蒞Đ:$sჟ O_cMJJa}K^Q~ M^Nt+r=%i/pD8=l<>YjիN-!gֱ͚lzJp_D>UruS?9L9lN5 |8{czvy'fd1s _V{'z?ΏDt~OEᗾWfE5ED1u gBˡ7#N^11Ge<8Eg mqeZ pDw5 E?)D^c;T_Ub.g_R>B*ֲ|3vaiaՄMԼO1t rNdQNF "iJI`*}Ohᇫo/[b 9 ]<,37wfZE}9Șhz_֊I04|ې-9U|9JmݟPoRw1abUVr#XF.{C }FKiǶPfFGK9^o(X\NJ\y))" t,4nTKe^D&X؍s;VڎCmwEgG r!j TcZ4W[.+`@4'yI$/_@hA_^=yɮ^%og!y lpFc8,}\eFմsphK|_M%n$L8ۉܗ?bK78gJx:4O`2'y~CO(!rG3O|睺/6J :`IhPPz)SpׇҮ|O5r)b$Ed=߶1w` : \1_XSUe`u1Z3~dhjw^~5jJoin'jd0NghS~M ᤾qWѿў_N &wg3\o}"h>Z_9ڍIx|q,Lڛ}U$2M|D7ӇHƪy,,3{#)0J޳{z`L7wz BϤ 9$h2JCδwPS /rtvd\rе(vھ/`´}Iqa6z3)Sin;,^T#6k^W{h'{1`z65_db}QFg^4t|xi)뗴o۾XP[20B5IeҋQ/݃m,*ABl VR;|.e|~CcDV= BPE)Y^yk!@Ipz0pʧՒ'տb++ǎ+ O+ޏ='"N̍豂nfIJ"v=ł,^qqe"Qo :LdVӻW^{[ zx~9ťn>_셟e1 RV3k8iKxXB+]7߼G2!Ә'⥏)eB`wN?W/^VLL/5K]ŒEEBͬ5:=0 xxb/G(<Ղ[f -b7r6iK)E( 8 zzO1xSQD.YLg\EAZ!j6!o"&}7G>F ҜX,?j\CLiiٌ9 Z3LSi(Uvy&;Ȯw;ۯpܵ'M>)PR8Uvn_fc(E eC+ue>0ûHI!ׇsE%ZC6]&%y昦/mC;X/ A!q(F a z:[Ig-S{fy>+zV)T_btALavB1o/9?j4-?,CSڻ?$m%j(re­G$:)KQDWc'ӕy\.JTڤ6f@4Kd5'Czsճx{lN žg㹈dGe;I<&ztH? 'ķYn~ |Щee62!0_]@QG"u)Q~|_9ލWZl,R{x?MYg_N\ކ,1$V':VD9f`(OM,.-KRWA|JR)_y Ai)'",] ;[uͥK6=LC3/koB~L1! )]N;eVGF8v'h&o.$>uX|7b7wrͩg!kbz~mm5w嬨xnBs~H7ŬQ 2ߌ}+Ͽmrbg\nѭ;|Ӻ3n0r.%Ѧ{Õ5;IWY҅`f< W}ydR:KU Ͻ\ƥgtZaG,L*+gWaeOtE=;n'?V>!Z;h& ~uo۾~$7,؉Pd/`}ߩ#]`7wVeE:h`0\bR(l}z#N,gz+Sላ2_ÇX|],F$y!g+O7kYBqƊ5,kN<}ۢӹIu܆l@c;B5@hZF N[we: x!CS.8{ GW_ <`GvʘJglLU 2ӭS{PEQP-e”l'4.x*p3qvuP^W{z/`qþM/IJ^ڼⒶe 5icSmZ:Xc:[M羓ܦc8X(daV2-F|J _iBHTں?C mwKG3]mfd|燽J: i4[PA*ܢ'N"UZ\䵂9)CNWdh>z41-ޚ%O9+8C,$]vx. viF##BP:kPqˤmCk |jR6 +0 XI|66`q4 "WUԚW&%B3u9cJK<.q)ܾADz)~%osKgZAW|Ѣ74o4e78O3敜=qGlר(BPIFuzuQ[{"bh*t~Y8=B&l1n>M ׳Ik"i=NV dX O0 ?K-htu m8e]eY$kl燦κ~UzqG~b$MfŏF~qj>-oT9xV[:}J/DAyꄲll$Llh$lX$3fiH:.r-9NX3½VjWq:yRoMMtR|\bE{h#2Kӵb-p268IЛV΂%9ZgY8{f"m/h.ꟸdu!|{C0^$NmR^1 BF۟""5?Aӟrvk>|8s)L D).7Hg$¾"M`/mVq:>sVpBSFGϿR2&y ݑg* NM%Y)grj239rYe|R(_1I⽠?Q :cF2RFc#6{d9vİ#|*rIHBMDז梹Wr> 4Gienߙ:~%L>;&d<"Qpx-ڝ5W7AUW e.ZD߼!;[?pCnنӣ$ûijo9TGo_ڒX &X3֚l 1 e3%0QE'yDh_}T%'w?e3Dw|w.YB*6f0t94[CulJ:krRUN`4|]SL emUdNc/`\;%9ScQ^;G}i~/DZ].¼:3-soHu-/XF.`Q2`*Yra++T^a|jɂXRgu1 Ӂ<~// )#+ZK^w 9Uf֍e#JX> g8ٰZI4Jߘ?i:˭9GU``@5S m󨷐ih(GyODAᲱ 2f=rcR&-k$q=pdxw̯a-X1: *h]@3( B G8N4$3-+τ =Y~mڮǔ[T]ߘaPhF؆)د%cWddn !|K#Bg4U>S@g2s,|_e+5b@oڄzHLG] ^2̴۾k!5 av S]7 )H}DE5]m?04OHXU6=ɩ#c.'ji5?lɿ $l;_,o^ IiҿkP~.Ntx0QFfc(^լZGOBްk<ӛ}R\u$o>|3V^POG/ 94z1/J6pi"'^UL܀}Z }7'CyY}!(e sM"13<={ >(oC—Pnq](].s[;~\m%0l~fXd.3-~̂)ڳUٵHOP1n(`V?⮍hƹXi 5 |F+9*Q1.)f(>^Yvtʛl.-7fsǕ M)M*uP=rPi0ZJ:]-hX>VA]NBQeTwg18m`ӷ p@ס=A+I_8b$ HXX%K5@BfkKy08yo}n?3o5YXF:ڢb,oKfQ; 5Z ‚!SOy-M$0 o3]b )zWz k ~$=Psp.ʀ@Iu0$r6O S1opǑ8cӁ@ZnW.8iJjRIjq4pRgLޥݤBؾ58@~l(U5><6{&絏OLl&!ies=B"bWZ_Fx~y)xRIt\N|Y NύUAy.G%'\pm0*|\pa{rpz^kOg" UZ %o#pfo0Rgg,$eMP 3pmV3oF ICh*Lz%XX^λΥ fpF hx#kӓTE"5^rԅ4=4}KZQb&F[hf]ln9>Ð+J;ARՇ 4Z@DNavE uX]7g D d`6.Vv2rJ̗ul?w ƭ M`Q$Rhj; xUX2Y5a+_ -:ņfRϐ Ҽ"P}1=ryJ!Ɔ䪆1`C/= TāH/6l9ScM AXqmQ%f\&mgĺ|rL^1tpWEUu /ذg7tژ©rسzw-5_):˲t6i}%7_O{Q=$v?J ~KQusimJ omAZqWk^I~1=4E'/MDQo^a.>?˃)t~bRy*L/kC{EZd!W޲6=60' ;#QZö7?i7GY(u̗ t<-SQhBY\.^C{x R3i ژ 8~>"zm*ɅU߻WԳڑK#W|iL=YNk-,IW)fdQ۹}M\8,U\:$hZ3P.Υ&'>d8vxs-]Kv4 \itk73ˬ)Z( endstream endobj 65 0 obj << /Length1 1967 /Length2 6618 /Length3 0 /Length 7802 /Filter /FlateDecode >> stream xڍ8?;$>td=C9889s%J(^){2ӓ]8~~\9 쑶0u$#TtMLb)7  Nm CH_  TQ<]8Kˉb(9@t-$&VAN\? ;>,++-+PrvP 8p1'ˉx{{ CH5>Aq`h f A` r&Np?c8+@B<0k0?d?~GLG !ܡ_8p}uaF"h$.Bmq_Cu%CS[wǠpןE~^C`Ф?S`vs}.7_G;a.riLg6G`Ig_w/'!8d0R?4 `PE`0`0G8,; s,DqDd0{$ELu~KTVF~B`@HL\d%f_PDi"?pg s4|+!q @go)*)j^_!3u#uOW_~?wM'H~ jguapOjb QB89H8Z7c~M̿׀ G hrv.7_.n[Q azbRKLRvka p$JI"*?M48Cb3$hA28Dirp YAR8&sDlϐ, bIਸ,qqRD:#t 2:!_w'+xA)@/5VL כϋ;丝A0W)K! 7|#\ag%mgq]6 рqRQA:"q&NϿ N_'\ypa~=~|`vSHU*.y -IPtEbI̖ԘV CT QJ+QsĊԹ3X%8UL`(VZSlEի[6{GFXcYeNyk7bddC[Zʕ+B)l%]V_?|'&5T>66kZZ;`{]8m ٢ K8}z%4UUt}YhS:"aYjZGq%VKojR XcΛhAkK23MQBeyťA aNw^u෬bλ6~:tSKl)Bu /0 F%w ofÓ!V_|>1E_$gɕ T  ҉ V{]>>*61&=W0'3sgBZ4l]ޖ.W0`⪏GWV!)@ٔ, tP~&r޹lfY34ľM<t$=\jQNWSyўϝf(>kYdVd**ɕ-sB d͗^!qk-JOU=5KֺRPZ˜(>ˉV]N&9vg3UR mQx:za$ υ2WF._w>J6k{*h}4?c| 8G/E9q̄# wvIWe!Q&{7r<ǖ.AQSldy3ϋcjbQW\2nO4[9(ܿ1pSnt-mI ؖ4N\sx83Um/πAf{N=](,r$uC5vѧ.ÎdL+d9n4AjRw:9_~OAldcsgW*,? Ww'fU݂B&zOP'{:y5xCWH[݉X 0 a nhbSCP^e&lKě_۠ }DjIߕLJvIJTj?I?!i:R,GfaP!rRRߓ갭IF鲰ns^˂D#pYx}.gYw ƃC/0ͨ]YI3K8}ce]6[WF\k&n\,o3j0I,1_2"N\^UzP#5::vuoC Vg9b=2k֘H{R/حOp3^EXdy:d{|Α'lU/;)7|x*5d?؎Sێ<]KmKulBErpe~sACdBG w&7SC{s~GeGBO5ޠUc|Y]iit$AX7c&|vx\psĉFccxӳϥfȡU'",kEf]̓X [K2>:eÈJcDMt^ܴ{fimJڠA K>Pl/QQg[朒 "=d3{,lqr/Q_P ߜ6atoq@YrKb&oڒ :-}ožEN|.fYTjx7KVE[#JXMwʌ$5O?IԀ}Y $]^л5/֌ff~rb;# zUbOe~W M[zߏSŦB\T#O/SR"TA`Q7hq<$Z}Hx@sbZVG?f3Ʊ/lApqaiF;]o֛x׈K')6}Jt+ӁB+D\r/b{߾/^|(;#®l^zYq('bO*c0p-WAHe^KA1w#uJPZ)e&?Ӱ j}}O*)ǻsnT=65M&;ʴj u׳-;4ϴ\ ĤBayEz꙱\u8.`PШf`{_C;4٢Myּʹ̓6ߌ Y7lY>~0I;oL޼ cj=/}_5JNlfxJLQ{7-)\V_u_x0F܀%'pK*?69<[BQV CQi-V<# h;O񐡆 wcJɝХ`aw[4q, WHF;Vrjz]\um!nu!_@J\[m-ej91&D3.H-TS 8oS9oWE)ſ(`4oxYm$@A^R*6;ΟEX Obfn=7nMڪ~']&P`=mqeq2oQjH}IZסc,LV9Ws)訃0BN :jDK!(nw}4IauHrg)^_<3x0Iqk4V4pjZ-w{G{ZܦM8Sh*ґEu;ہS'̮M߭;Q9E6uDΜY6_CU{$qT!{GP7#\*;h;VTb *ZE3^Sa ''Gyҡkzt!jvăZ 6N͇/?Cy4v7wx-c\A@&!6Pys;^S0K!M"E#`Ӥ!cYg 稔 Fz9m;ȿYD'x}y;1_%i&s`bxA2-kWlPwiS-k05_r sY,$~TTny%oA.7D33u},jdislKeM?p/mQxNKH'e^ɹFeADX\a[X󛃒 M{ 2B'b3MOݧJؘK2<:yDkO:(`'I!^E8JU0RѢ@M M]hC@mԗFYoPX(ϊOsKo3h5z`\2:pxUײ+cȻʩӔvoTE:9a'U_} ΢w:֍-ƬMRŪ:܊eQ.uQG% woXwx$t>;3pT.F1Œ*&ه,/?~3P' ^mTNf.r/a]ͼ4Bc`I^2䩨͇IE6Ki.IBK'  >GzMc_D &cG,j%)|ZWJv_1sˑX\9r_ /h+9?BKB*37 #`7 ]^#}Ume=tl]bAM>bQj~*@ђcX5{cʌf5LrDS5aa͡02t~ؤL·osCGbM8`M7< d^Mܪj0.|5ɝrŇ7嗗%Bދhg-EYє ɶ%e65nJe3on쨲·E +VlYq 70Qrjq-}-U%Cv PP@peK|C;9~#?I:Oi`S+=jM_`{{鼿OTB7yh+V{HkZ[+,kn-`q݆[APj̏TK&el>9j_uJx/C#U]"m7R%t!,#3;0z3f\;?Ta}nK%WںU޻Z䚰&!g­]餢 |br~o8؊ /%\aλCXHXy~&y{q6hf{ vTfyBZK vVbI6ïEU/,nG{폃?fڿT-U2%f@Շ@L-S1y#7Xqf5hyt6ADZ|oҳf[9Q'yڬJ-1Kh6>dedM]b3jdMrX.p+>|n}O˛A-ʟ*0B}@K[]tH48d}+Xr0[\5VI~{EځGJ޲oI҆Eо1(f2k~kEIHˍw;- T'|5 f6^Д33{YD:{`\uD@0uJ宥̦#ŗNjX0xE7C'`sխK<~ƐUeP endstream endobj 67 0 obj << /Length1 737 /Length2 969 /Length3 0 /Length 1537 /Filter /FlateDecode >> stream xmT{4i\Q/1eBAE̋>f\:BrdS˶tR)*E-V)%i?t=?{}ykbA >"V< 8l[ (J @ S $E3!kAbTI0bB \.^.I 6]! |{='?xBŘxcBK! D$+ $p6Iʞ !I"HB||pY xE{]SR: xw>iMF8f aB H gXGN d_C4!)F2J 0hIC qcIl 8TKҢ⑴V\;%I=8((Z{A% s"L&Q^i} \U7B{ZDȟֳ:v?ZQś1ZͅWni|Rdj c6uQiy.COUwhan+JnYmPT5$VY.va;CJ~t쩢)Q:{O>XqkIkF6]^8UXy[s6!%l;._.6~^dc뱪Ϫ fF Ӂs1Q>QX03L8 u' 2Ɲ$YbݦZɖfgg v}5G]ߜ+IӼ蔿nm<`~e!i_Z <\m?_-[[\+kě5?:6xtvX0eƅ&eft*G~غd*#R /)xi`7ovmLsä.|ղ)C* endstream endobj 71 0 obj << /Producer (pdfTeX-1.40.14) /Creator (TeX) /CreationDate (D:20140827165339-04'00') /ModDate (D:20140827165339-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/MacPorts 2013_5) kpathsea version 6.1.1) >> endobj 8 0 obj << /Type /ObjStm /N 50 /First 379 /Length 2271 /Filter /FlateDecode >> stream xZ]S7Z}K3'!!@J c0MJi׻`;VG9GGҮ%˘`>0!pIkLaK&3&01k0SIż YPt :IYl!c Tk,2b` 5LK&QL+OC0%=ځ)G+ xj YόEsr6c&dVHV S\1Y0'b6Bas3Aw`9s4]'<8I< kHɐ-x`y_ٔ)dwz2ȧpPOF ̃8ȸfs{PxUa**xh~~3cG%[ՅfRV- Wa9{+r?J)[G@DŽ4-SA[(}АB@=U+4jԽ@7t^PtA*ײ<5O"uR??Ay{]A6_]s1]쑱nUEMKwͲ~uW]P;d5 EDT:RjݦزlijG2i8N,KVX k0]]jvZ$ l1^ŹweiFo88 b]XAިkދ ʊG ӤN8"h2 cIeA%Gǀ%ZX3rݲTBR|l,՗^St8qw8ֺ6բ-)ZpMuWT:ua^[UʂcMhvՅ@k#ىي;l9ļG @ GDcc;Ef <#H{"y D1%USi}+SGnіL~OA+_mx=(ZJ7MڐZzEBˣ%yX%8J}\KJ\>Ka-)H Vgꏼ]9UB՗ʂw5&-Y1e --Tb-x uR*PJE;hLw}g_Yt DEg, apVMrGUz+k|lqƜ*N uSKz*<ڠ)k(ZM KfKO0Ic&)$i@8N}]ԡ ÌdPȌed18ۍ'ZzO3 z]b3 bn㜌'83(C2dkծtAxOl?>/ )?=C~GO~/%eί]YM9' )_c~7OjQJ݇׻__]t}puhEiTG Y~r|* J5v hjv_5$Ɛb3sf@|;=x"4E=Qbs>}GϾ_ /GU+\Og#HZMMG7gЋkVYA̚$OE"F6sȾ%IWj!D[)F྆5ak_}&kg2G)4uk[[r/˺.b l !QsniгR֥=UCmdE-fV$|F*9o Np YQ<%t:1A6O>{ lk"_ßz{.[`KTkTa_Q:zY],M4hBà[8:=BQhq}ꁻ/dlLZ_‘hAGde/l lZwlaMFmE:DSV%77re66PSnS7_ [C%?@x+-o#j iRM53e ntX#*@\LΣ;x%U7Bʉ!MPL#46 endstream endobj 72 0 obj << /Type /XRef /Index [0 73] /Size 73 /W [1 3 1] /Root 70 0 R /Info 71 0 R /ID [<97DF62B20E81F34C5273BEE92F271731> <97DF62B20E81F34C5273BEE92F271731>] /Length 211 /Filter /FlateDecode >> stream x%9NPEE@APVA)L< ''6@MMh ;ؘ 36$!D)@ սhG B艠:AES HD㩈w]gDi굸8'jDJѮ{)0՝HȊKq%r"/Ex"!/[btU&_JN>\5r5vœW? endstream endobj startxref 116306 %%EOF gWidgets/inst/doc/gWidgets.Rnw0000644000176000001440000020525112377442527016070 0ustar ripleyusers\documentclass[12pt]{article} \newcommand{\VERSION}{0.0-7} %\VignetteIndexEntry{gWidgets} %\VignettePackage{gWidgets} %\VignetteDepends{methods,gWidgetstcltk} \usepackage{times} % for fonts \usepackage[]{geometry} \usepackage{mathptm} % for math fonts type 1 \usepackage{graphicx} % for graphics files %%\usepackage{floatflt} % for ``floating boxes'' %%\usepackage{index} %%\usepackage{relsize} % for relative size fonts \usepackage{amsmath} % for amslatex stuff \usepackage{amsfonts} % for amsfonts \usepackage{url} % for \url, \usepackage{hyperref} \usepackage{color} %%\usepackage{fancyvrb} %%\usepackage{fancyhdr} %%\usepackage{jvfloatstyle} % redefine float.sty for my style. Hack %% squeeze in stuff %%\floatstyle{jvstyle} %%\restylefloat{table} %%\restylefloat{figure} %%\renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} %% Fill these in % \pagestyle{fancy} % \usepackage{fancyhdr} % \pagestyle{fancy} % \fancyhf{} % \fancyhead[L]{\code{gWidgets}} % \fancyhead[C]{} % \fancyhead[R]{\sectionmark} % \fancyfoot[L]{} % \fancyfoot[C]{- page \thepage\/ -} % \fancyfoot[R]{} % \renewcommand{\headrulewidth}{0.1pt} % \renewcommand{\footrulewidth}{0.0pt} %% My abbreviations \newcommand{\pkg}[1]{\textbf{#1}} \newcommand{\code}[1]{\texttt{#1}} \newcommand{\RFunc}[1]{\code{#1}} %% no () \newcommand{\RArg}[1]{\code{#1=}} \newcommand{\RListel}[1]{\code{\$#1}} \newenvironment{RArgs}{\begin{list}{}{}}{\end{list}} \begin{document} \thispagestyle{plain} \title{Examples for gWidgets} \author{John Verzani, \url{gWidgetsRGtk@gmail.com}} \maketitle %% Sweave stuff \SweaveOpts{keep.source=TRUE} \section*{Abstract:} [This was updated last for \pkg{gWidgets\_0.0-41}.]\\ Examples for using the \pkg{gWidgets} package are presented. The \pkg{gWidgets} API is intended to be a cross platform means within an R session to interact with a graphics toolkit. Currently, the API can be used through: \begin{itemize} \item \pkg{gWidgetsRGtk2} for \pkg{RGtk2} package which is the most complete implementation. \item \pkg{gWidgetstcltk} for the \pkg{tcltk} package which is the easiest to install (for windows users) but not as fully implemented or polished. \item \pkg{gWidgetsQt} for the \pkg{qtbase} package. This package allows the Qt toolkit to be used from within R. It is being developed and is available from r-forge. \item \pkg{gWidgetsrJava} for the \pkg{rJava} package. This package may be deprecated in the near term if no interest is shown. \end{itemize} The \pkg{gWidgetsWWW} package is an independent implementation for web programming. It uses the EXT JS JavaScript libraries to provide R to web interactivity. It leverages the \pkg{rapache} package for server installs, and has a user-only web browser leveraged from the \pkg{Rpad} package. Unlike the other implementations, this package is stand alone and does not use \pkg{gWidgets} itself. % Finally, a partial port for the \pkg{RwxWidgets} package is started, % but awaits completion of that package. The API is intended to facilitate the task of writing basic GUIs, as it simplifies many of the steps involved in setting up widgets and packing them into containers. Although not nearly as powerful as any individual toolkit, the \pkg{gWidgets} API is suitable for many tasks or as a rapid prototyping tool for more complicated applications. The examples contained herein illustrate that quite a few things can be done fairly easily with more complicated applications being pieced together in a straightforward manner. To see a fairly complicated application built using \pkg{gWidgets}, install the \pkg{pmg} GUI (\url{http://www.math.csi.cuny.edu/pmg}), which is on CRAN. The \pkg{traitr} package implements a model-view-controller programming style for GUI development. It uses \pkg{gWidgets} to provide the GUI components. %\setcounter{tocdepth}{3} %\tableofcontents \section{Background} The \code{gWidgets} API is intended to be a cross-toolkit API for working with GUI objects. It is based on the iwidgets API of Simon Urbanek, with improvements suggested by Philippe Grosjean, Michael Lawrence, Simon Urbanek and John Verzani. This document focuses on the more complete toolkit implementation provided by the \pkg{gWidgetsRGtk2} package.~\footnote{Occasional differences with \pkg{gWidgetsQt}, \pkg{gWidgetstcltk}, or \pkg{gWidgetsrJava} are pointed out in braces. The major differences from the \pkg{gWidgets} API are documented in the help files given by the package name, e.g. \pkg{gWidgetstcltk}} The GTK toolkit is interfaced via the \pkg{RGtk2} package of Michael Lawrence, which in turn is derived from Duncan Temple Lang's \pkg{RGtk} package. The excellent \pkg{RGtk2} package opens up the full power of the GTK2 toolkit, only a fraction of which is available though \pkg{gWidgetsRGtk2}. The \code{gWidgets} API is mostly stable, but does occasionally have additional methods and constructors added. If a feature seems lacking, please let the author know. \section{Overview} The basic tasks in setting up a GUI involve: constructing the desired widgets, laying these widgets out into containers, and assigning handlers to respond to user-driven events involving the widgets. The \pkg{gWidgets} package is geared around these tasks, and also around providing a familiar means to interact with the widgets once constructed. The actual toolkits have much more flexibility during the layout of the GUI and afterwards in pragmatically interacting with the GUI. Each widget constructor in \pkg{gWidgets} includes the arguments \code{container} to specify a parent container to place it in; \code{handler}, to specify a handler to respond to the main event that the widget has; and \code{action}, which is used to pass extra information along to any handler. Each widget when constructed returns an object of S4 class which can be manipulated using generic functions, some new and some familiar. The basic widgets are likely familiar: buttons, labels, text-edit areas, etc. In addition, there are some R-specific compound widgets such as a variable browser, data frame viewer, and help viewer. In contrast to these, are a few basic dialogs, which draw their own window and are modal, hence do not return objects which can be manipulated. The examples below introduce the primary widgets, containers, and dialogs in a not-so systematic manner, focusing instead on some examples which show how to use \pkg{gWidgets}. The man pages are also a source information about the widgets, see \code{?gWidgets} for more detail. For differences between the toolkit implementation, see the man page for the package name, for example, \code{?gWidgetstcltk}. This document is a vignette. As such, the code displayed is available within an R session through the command \code{edit(vignette("gWidgets"))}. \section{Installation} In case you are reading this vignette without having installed gWidgets, here are some instructions focusing on installing \pkg{gWidgetsRGtk2}. More details are found at the \pkg{gWidgets} website \url{http://www.math.csi.cuny.edu/pmg/gWidgets}. Installing \code{gWidgets} with the \code{gWidgetsRGtk2} package requires two steps: installing the GTK libraries and installing the R packages. \subsection{Installing the GTK libraries} The \code{gWidgetsRGtk2} provides a link between \code{gWidgets} and the GTK libraries through the \code{RGTk2} package. \texttt{RGtk2} requires relatively modern versions of the GTK libraries (2.8.12 is suggested). These may need to be installed or upgraded on your system. In case of \textbf{Windows} you can do this: \begin{enumerate} \item Download the files from \href{http://gladewin32.sourceforge.net/modules/wfdownloads/visit.php?lid=102}{http://gladewin32.sourceforge.net/modules/wfdownloads/visit.php?lid=102} \item run the resulting file. This is an automated installer which will walk you through the installation of the Gtk2 libraries. \end{enumerate} For Windows users, the following command, will do this and install \code{pmg}. (Likely you are better off with the previous method.) \begin{Sinput} > source("http://www.math.csi.cuny.edu/pmg/installPMG.R") \end{Sinput} In Linux, you may or may not need to upgrade the GTK libraries depending on your distribution. If you have a relatively modern installation, you should be ready. For Mac OS X there is also a packaged port of the GTK run time libraries available through at \url{http://r.research.att.com/}. When the author used this quite some time ago, the \pkg{cairoDevice} package failed (this may be fixed by now). As such, the the macports (\url{http://www.macports.org}) project was used to install its \texttt{gtk2} package. Once macports is installed, the command \begin{verbatim} sudo port install gtk2 \end{verbatim} will install the libraries (although it may take quite a while). There are more details on RGtk2 at \href{http://www.ggobi.org/rgtk2}{RGtk2's home page}. \subsection{Install the R packages} The following R packages are needed: \texttt{RGtk2}, \texttt{cairoDevice}, \texttt{gWidgets}, and \texttt{gWidgetsRGtk2}. Install them in this order, as some depend on others to be installed first. All can be downloaded from CRAN. These can all be installed by following the dependencies for \code{gWidgetsRGtk2}. The following command will install them all if you have the proper write permissions: \begin{verbatim} install.packages("gWidgetsRGtk2", dep = TRUE) \end{verbatim} It may be necessary to adjust the location where the libraries will be installed if you do not have the proper permissions. For MAC OS X, the source packages might be desired if you installed via macports, not the default ``mac.binary.'' Use the \code{type=} argument, as follows: \begin{verbatim} > install.packages("gWidgetsRGtk2", dep = TRUE,type = "source" ) \end{verbatim} % On occasion, newer versions are available from % \href{http://www.math.csi.cuny.edu/pmg}{gWidgets's website}. To % install from here add the \texttt{repos=} argument, as follows: % \begin{verbatim} % > install.packages("gWidgetsRGtk2",dep = TRUE, repos = "http://www.math.csi.cuny.edu/pmg") % \end{verbatim} [The \pkg{gWidgetsQt} package requires the \pkg{qtbase} package which is not yet on CRAN, but rather is installed through r-forge.] [The \pkg{gWidgetstcltk} requires the 8.5 version of tcl/tk which comes with the windows version of R as of 2.7.0, but typically needs to be installed manually for linux and mac machines, as of this writing.] [The \pkg{gWidgetsrJava} package is installed similarly. However, it requires \pkg{rJava}. These should install through the dependencies, so \begin{verbatim} > install.packages("gWidgetsrJava", dep = TRUE) \end{verbatim} should do it. The \pkg{rJava} has some potential issues with the mac version of R that can arise if R is compiled from source.] [The \pkg{gWidgetsWWW} package is altogether different. The package requires \pkg{rapache} to be installed to be used in server mode. As well, the apache web server must also be configured. The package can be used locally through a standalone web server. ] \section{Loading gWidgets} We load the \code{gWidgets} package, using the \code{gWidgetsRGtk2} toolkit, below: following <<>>= require(gWidgets) ##options("guiToolkit"="RGtk2") options("guiToolkit"="tcltk") @ <>= require(gWidgetstcltk) @ When \code{gWidgets} is started, it tries to figure out what its default toolkit will be. In this examples, we've set it to be ``gWidgetsRGtk2.'' If the option was not set and there is more than one toolkit available, then a menu asks the user to choose between toolkit implementations. [For \pkg{gWidgetsQt} use ``Qt'', for \pkg{gWidgetsrJava} use ``rJava'' in the \RFunc{options} call or ``tcltk'' for the \pkg{gWidgetstcltk} package.] [The \pkg{gWidgetsWWW} package is different, as it doesn't use the \pkg{gWidgets} package for dispatch. It is loaded directly via \code{require(gWidgetsWWW, quietly=TRUE)} -- using the \code{quietly} switch, as anything output to STDOUT is sent to the browser.] \section{Hello world} We begin by showing how to make various widgets which display the ubiquitous ``Hello world'' message. \begin{figure}[htbp] \centering \begin{tabular}{l@{\quad}l} \includegraphics[width=.35\textwidth]{button}& \includegraphics[width=.35\textwidth]{label}\\ \includegraphics[width=.35\textwidth]{radio}& \includegraphics[width=.35\textwidth]{droplist} \end{tabular} \caption{Four basic widgets: a button, a label, radio buttons, and a drop list.} \label{fig:basic-widgets} \end{figure} Now to illustrate (Figure~\ref{fig:basic-widgets} shows a few) some of the basic widgets. These first widgets display text: a label, a button and a text area. First a button: <<>>= obj <- gbutton("Hello world", container = gwindow()) @ Next a label: <<>>= obj <- glabel("Hello world", container = gwindow()) @ Now for single line of editable text: <<>>= obj <- gedit("Hello world", container = gwindow()) @ Finally, a text buffer for multiple lines of text: <<>>= obj <- gtext("Hello world", container = gwindow()) @ The following widgets are used for selection of a value or values from a vector of possible values. First a radio group for selecting just one of several: <<>>= obj <- gradio(c("hello","world"), container=gwindow()) @ Next, combo box, (was called a droplist) again for selecting just one of several, although in this case an option can be give for the user to edit the value. <<>>= obj <- gcombobox(c("hello","world"), container=gwindow()) @ A combo box can also allow its value to be entered by typing, <<>>= obj <- gcombobox(c("hello","world"), editable=TRUE, container=gwindow()) @ For longer lists, a table of values can be used. <<>>= obj <- gtable(c("hello","world"), container=gwindow()) @ This widget is also used for displaying tabular data with multiple columns and rows (data frames). For this widget there is an argument allowing for multiple selections. Multiple selections can also be achieved with a checkbox group: <<>>= obj <- gcheckboxgroup(c("hello","world"), container=gwindow()) @ For selecting a numeric value from a sequence of values, sliders and spinbuttons are commonly used: <<>>= obj <- gslider(from=0, to = 7734, by =100, value=0, container=gwindow()) obj <- gspinbutton(from=0, to = 7734, by =100, value=0, container=gwindow()) @ Common to all of the above is a specification of the ``value'' of the widget, and the container to attach the widget to. In each case a top-level window constructed by \RFunc{gwindow}. \subsection{Using containers} In this next example, we show how to combine widgets together using containers. (Figure~\ref{fig:hello-world}.) <<>>= win <- gwindow("Hello World, ad nauseum", visible=TRUE) group <- ggroup(horizontal = FALSE, container=win) obj <- gbutton("Hello...",container=group, handler = function(h,...) gmessage("world")) obj <- glabel("Hello...", container =group, handler = function(h,...) gmessage("world")) obj <- gcombobox(c("Hello","world"), container=group) obj <- gedit("Hello world", container=group) obj <- gtext("Hello world", container=group, font.attr=list(style="bold")) @ As before, the constructors \RFunc{gbutton}, \RFunc{glabel}, \RFunc{gedit} and \RFunc{gtext} create widgets of different types~\footnote{We refer to \code{gbutton} as a constructor, which it is, and also a widget class, which it technically isn't.}. The button looks like a button. A label is used to show text which may perhaps be edited. [Editing text isn't implemented in all toolkits. and in personal experience seems to be confusing to users.] A combobox allows a user to select one of several items, or as illustrated can take user input. The \RFunc{gedit} and \RFunc{gtext} constructors both create widgets for inputting text, in the first case for single lines, and in the second for multiple lines using a text buffer. \begin{figure}[htbp] \centering \includegraphics[width=.35\textwidth]{hello-world} \caption{Hello world example} \label{fig:hello-world} \end{figure} These widgets are packed into containers (see \code{?ggroup} or \code{?gwindow}). The base container is a window, created with the \RFunc{gwindow} function. A top-level window only contains one widget, like a group, so we pack in a group container created with \RFunc{ggroup}. (Top-level windows also may contain menubars, toolbars and statusbars.) The \RFunc{ggroup} container packs in widgets from left to right or top to bottom. Imagine each widget as a block which is added to the container. In this case, we want the subsequent widgets packed in top to bottom so we used the argument \code{horizontal=FALSE}. For the button and label widgets, a handler is set so that when the widget is clicked a message dialog appears showing ``world.'' Handlers are used to respond to mouse-driven events. In this case the event of a widget being clicked. See \code{?gWidgetsRGtk-handlers} for details on handlers. Note the handler has signature \code{(h,...)} where \code{h} is a list with components \code{obj} referring to the widget the handler is called on, \code{action} referring to the value passed to the \RArg{action} argument and perhaps others (eg. \code{dropdata} for drag-and-drop events, and \code{x} and \code{y} for \code{ggraphics} click events.). The \code{...} in the signature, may contain information passed along by the underlying toolkit and is necessary but not generally employed. The message is an instance of a ``basic dialog'' (see \code{?gWidgets-dialogs}). The dialogs in \code{gWidgets} are modal, meaning R's event loop is stopped until the dialog is answered. (This can be annoying if a dialog appears under another window and can't be seen!) As such, they don't return an object which has methods defined for it, as by the time they can be accessed they have been dismissed. Instead, they return a value like a logical or a string. \section{Making a confirmation dialog} Let's see how we might use widgets to create our own confirmation dialog, one which is not modal. We want to have an icon, a label for the message, and buttons to confirm or dismiss the dialog. The \RFunc{gimage} constructor allows images to be shown in a widget. In \pkg{gWidgetsRGtk} there are several stock images, which can be listed with \RFunc{getStockIcons}. We will use ``info'' below. First we define a function for making a dialog. This one uses nested group containers to organize the layout. (Alternately the \RFunc{glayout} constructor could have been used in some manner.) <<>>= confirmDialog <- function(message, handler=NULL) { window <- gwindow("Confirm") group <- ggroup(container = window) gimage("info", dirname="stock", size="dialog", container=group) ## A group for the message and buttons inner.group <- ggroup(horizontal=FALSE, container = group) glabel(message, container=inner.group, expand=TRUE) ## A group to organize the buttons button.group <- ggroup(container = inner.group) ## Push buttons to right addSpring(button.group) gbutton("ok", handler=handler, container=button.group) gbutton("cancel", handler = function(h,...) dispose(window), container=button.group) return() } @ The key to making a useful confirmation dialog is attaching a response to a click of the ``ok'' button. This is carried out by a handler, which are added using the argument \RArg{handler} for the constructor, or with one of the \code{addHandlerXXX} functions. The handler below prints a message and then closes the dialog. To close the dialog, the \RFunc{dispose} method is called on the ``ok'' button widget, which is referenced inside the handler by \code{h\$obj} below. In \code{gWidgets}, handlers are passed information via the first argument, which is a list with named elements. The \RListel{obj} component refers to the widget the handler is assigned to. Trying it out produces a widget like that shown in Figure~\ref{fig:confirmDialog} \begin{figure}[htbp] \centering \includegraphics[width=.35\textwidth]{confirmDialog} \caption{Confirmation dialog} \label{fig:confirmDialog} \end{figure} <<>>= confirmDialog("This space for rent", handler = function(h,...) { print("what to do... [Change accordingly]") ## In this instance dispose finds its parent window and closes it dispose(h$obj) }) @ %%$ \section{Methods} Widgets are interacted with by their methods. The main methods are \RFunc{svalue} and \RFunc{svalue<-} for getting and setting a widgets primary value. The following silly example illustrates how clicking one widget can be used to update another widget. <<>>= w <- gwindow("Two widgets") g <- ggroup(container = w) widget1 <- gbutton("Click me to update the counter", container=g, handler = function(h,...) { oldVal <- svalue(widget2) svalue(widget2) <- as.numeric(oldVal) + 1 }) widget2 <- glabel(0, container=g) @ The value stored in a label is just the text of the label. This is returned by \RFunc{svalue} and after 1 is added to the value, replaced back into the label. As text labels are of class ``character,'' the value is coerced to be numeric. There are other methods (see \code{?gWidgetsRGtk-methods}) that try to make interacting with a widget as natural (to an R user) as possible. For instance, a radio button has a selected value returned by \RFunc{svalue}, but also a vector of possible values. These may be referenced using vector, \code{[}, notation. Whereas, a notebook container has a \RFunc{names} method which refers to the tab labels, which may be set via \code{names<-} and a \RFunc{length} method to return the number of notebook pages. \section{Adding a GUI to some common tasks} A GUI can make some command line tasks easier to perform. Here are a few examples that don't involve much coding in \code{gWidgets}. \subsection{\RFunc{file.choose}} The \RFunc{file.choose} function is great for simplifying a user's choice of a file from the file system. A typical usage might be \begin{Soutput} source(file.choose()) \end{Soutput} to allow a user to source a file with a little help from a GUI. However, in many UNIX environments, there is no GUI for \RFunc{file.choose}, only a more convenient curses interface. With the \RFunc{gfile} dialog, we can offer some improvement. This dialog returns the name of the file selected, so that \begin{Soutput} source(gfile()) \end{Soutput} can replace the above. More in keeping with the \code{gWidgets} style, though, would be to give a handler when constructing the file chooser. The \code{file} component of the handler argument gives the files name (not \code{svalue(h\$obj)}, as \code{gfile} does not return an object to call \code{svalue} on). For example, the function below is written to give some flexibility to the process: %%$ <<>>= fileChoose <- function(action="print", text = "Select a file...", type="open", ...) { gfile(text=text, type=type, ..., action = action, handler = function(h,...) { do.call(h$action, list(h$file)) }) } @ The \RArg{action} argument parametrizes the action. The default above calls \RFunc{print} on the selected file name, hence printing the name. However, other tasks can now be done quite simply. For example, to \RFunc{source} a file we have: %% not in <<>>=/@ as they are modal and mess up Sweave \begin{Sinput} > fileChoose(action="source") \end{Sinput} Or to set the current working directory we have: \begin{Sinput} > fileChoose(action="setwd", type="selectdir", text="Select a directory...") \end{Sinput} \subsection{\RFunc{browseEnv}} \label{sec:browseEnv} The \RFunc{browseEnv} function creates a table in a web browser listing the current objects in the global environment (by default) and details some properties of them. This is an easy to use function, but suffers from the fact that it may have to open up a browser for the user if none is already open. This may take a bit of time as browsers are generally slow to load. We illustrate a means of using the \RFunc{gtable} constructor to show in a table the objects in an environment. The following function creates the data.frame we will display. Consult the code of \RFunc{browseEnv} to see how to produce more details. <<>>= lstObjects <- function(envir= .GlobalEnv, pattern) { objlist <- ls(envir=envir, pattern=pattern) objclass <- sapply(objlist, function(objName) { obj <- get(objName, envir=envir) class(obj)[1] }) data.frame(Name = I(objlist), Class = I(objclass)) } @ Now to make a table to display the results. We have some flexibility with the arguments, which is shown in subsequent examples: <<>>= browseEnv1 <- function(envir = .GlobalEnv, pattern) { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv1")) } @ Tables can have a double click handler (typically a single click is used for selection). To illustrate, we add a handler which calls \RFunc{summary} (or some other function) on a double-clicked item [Qt's behaviour is OS dependent]. (The first \code{svalue} returns a character string, it is promoted to an object using \code{get}) <<>>= browseEnv2 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv2"), action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } @ As a final refinement, we add a combobox to filter by the unique values of ``Class.'' We leave as an exercise the display of icons based on the class of the object. <<>>= browseEnv3 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container =gwindow("browseEnv3"), filter.column = 2, action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } @ [The \code{filter} argument is not available with \pkg{gWidgetsrJava} or \pkg{gWidgetsWWW}.] In \pkg{gwidgetsRGtk2} The \RFunc{gvarbrowser} function constructs a widget very similar to this, only it uses a \RFunc{gtree} widget to allow further display of list-like objects. [The \code{gtree} widget is not implemented in all of the toolkits.] \section{A gWidgetsDensity demo} \label{sec:repeating-plot} We illustrate how to make a widget dynamically update a density plot. The idea comes from the \code{tkdensity} demo that accompanies the \pkg{tcltk} package due to, I believe, Martin Maechler. We use the \RFunc{ggraphics} constructor to create a new plot device. For RGtk2, this uses the \pkg{cairoDevice} package also developed by Michael Lawrence. (This package takes some work to get going under OS X, as the easy-to-install RGtk2 libraries don't seem to like the package.) [In \pkg{gWidgetsrJava} the \pkg{JavaGD} package is used for a JAVA device. In theory this should be embeddable in a \pkg{gWidgets} container, but it isn't implemented, so a new window is created.] [In \pkg{gWidgetstcltk} there is no embeddable graphics device. (The \pkg{tkrplot} is different.) The \code{ggraphics} call would just put in a stub.] This demo consists of a widget to control a random sample, in this case from the standard normal distribution or the exponential distribution with rate 1; a widget to select the sample size; a widget to select the kernel; and a widget to adjust the default bandwidth. We use radio buttons for the first two, a drop list for the third and a slider for the latter. The \pkg{gWidgetstcltk} package is a little different from the other two, as it requires that a container be non-null. This is because the underlying \pkg{tcltk} widgets need to have a parent container to be initialized. As such, the following won't work. A working example will be given next for comparison. This one is left here, as the separation of GUI building into: widget definition; widget layout; and assignment of handlers, or call backs, seems to lead to easier to understand code. Proceeding, first we define the two distributions and the possible kernels. <>= ## set up availDists <- c(Normal="rnorm", Exponential="rexp") availKernels <- c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine") @ We then define the key function for drawing the graphic. This refers to widgets yet to be defined. <>= updatePlot <- function(h,...) { x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) plot(density(x, adjust = svalue(bandwidthAdjust), kernel = svalue(kernel)),main="Density plot") rug(x) } @ Now to define the widgets. <>= distribution <- gradio(names(availDists), horizontal=FALSE, handler=updatePlot) kernel <- gcombobox(availKernels, handler=updatePlot) bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, handler=updatePlot) sampleSize <- gradio(c(50,100,200, 300), handler = updatePlot) @ Now the layout. We use frames to set off the different arguments. A frame is like a group, only it has an option for placing a text label somewhere along the top. The position is specified via the \code{pos} argument, with a default using the left-hand side. <>= ## now layout window <- gwindow("gWidgetsDensity") BigGroup <- ggroup(cont=window) group <- ggroup(horizontal=FALSE, container=BigGroup) tmp <- gframe("Distribution", container=group) add(tmp, distribution) tmp <- gframe("Sample size", container=group) add(tmp,sampleSize) tmp <- gframe("Kernel", container=group) add(tmp,kernel) tmp <- gframe("Bandwidth adjust", container=group) add(tmp,bandwidthAdjust, expand=TRUE) @ Now to add a graphics device. <>= add(BigGroup, ggraphics()) @ [Again, if using \RFunc{gWidgetsrJava} this wouldn't place the device inside the \code{BigGroup} container.] A realization of this widget was captured in Figure~\ref{fig:gtkdensity}. \begin{figure} \centering \includegraphics[width=.6\textwidth]{gtkdensity} \caption{The gWidgetsDensity example in action.} \label{fig:gtkdensity} \end{figure} Now, as promised, we present a function that would work under any of the toolkits. The \code{ggraphics} call is not included, as this doesn't work with \pkg{gWidgetstcltk}. The key difference though is the containers are included in the creation of the widgets. The arguments that would be passed to \code{add} are included in the construction of the widget. <>= gwtkdensity <- function() { ## set up availDists <- c(Normal = "rnorm", Exponential="rexp") availKernels <- c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine") updatePlot <- function(h,...) { x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) plot(density(x, adjust = svalue(bandwidthAdjust), kernel = svalue(kernel))) rug(x) } ##The widgets win <- gwindow("gwtkdensity") gp <- ggroup(horizontal=FALSE, cont=win) tmp <- gframe("Distribution", container=gp, expand=TRUE) distribution <- gradio(names(availDists), horizontal=FALSE, cont=tmp, handler=updatePlot) tmp <- gframe("Sample size", container=gp, expand=TRUE) sampleSize <- gradio(c(50,100,200, 300), cont=tmp, handler =updatePlot) tmp <- gframe("Kernel", container=gp, expand=TRUE) kernel <- gcombobox(availKernels, cont=tmp, handler=updatePlot) tmp <- gframe("Bandwidth adjust", container=gp, expand=TRUE) bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, cont=tmp, expand=TRUE, handler=updatePlot) } @ \section{Composing email} This example shows how to write a widget for composing an email message. Not that this is what R is intended for, but rather to show how a familiar widget is produced by combining various pieces from \code{gWidgets}. This example is a little lengthy, but hopefully straightforward due to the familiarity with the result of the task. For our stripped-down compose window we want the following: a menubar to organize functions; a toolbar for a few common functions; a ``To:'' field which should have some means to store previously used e-mail addresses; a ``From:'' field that should be editable, but not obviously so as often it isn't edited; a ``Subject:'' field which also updates the title of the window; and a text buffer for typing the message. The following code will create a function called \RFunc{Rmail} (apologies to any old-time emacs users) which on many UNIX machines can send out e-mails using the \code{sendmail} command. This is not written to work with \code{gWidgetstcltk}. First we define some variables: <>= FROM <- "gWidgetsRGtk " buddyList <- c("My Friend ","My dog ") @ Now for the main function. We define some helper functions inside the body, so as not to worry about scoping issues. <>= Rmail <- function(draft = NULL, ...) { ## We use a global list to contain our widgets widgets <- list() ## Helper functions sendIt <- function(...) { tmp <- tempfile() cat("To:", svalue(widgets$to),"\n",file = tmp, append=TRUE) cat("From:", svalue(widgets$from),"\n", file=tmp, append=TRUE) cat("Subject:", svalue(widgets$subject),"\n", file=tmp, append=TRUE) cat("Date:", format(Sys.time(),"%d %b %Y %T %Z"),"\n", file=tmp, append=TRUE) cat("X-sender:", "R", file=tmp, append=TRUE) cat("\n\n", file=tmp, append=TRUE) cat(svalue(widgets$text), file=tmp, append=TRUE) cat("\n", file=tmp, append=TRUE) ## Use UNIX sendmail to send message system(paste("sendmail -t <", tmp)) ## Add To: to buddyList if(exists("buddyList")) assign("buddyList", unique(c(buddyList,svalue(widgets$to))), inherits=TRUE) ## Close window, delete file unlink(tmp) dispose(window) } ## Function to save a draft to the file draft.R saveDraft <- function(...) { draft <- list() sapply(c("to","from","subject","text"), function(i) draft[[i]] <<- svalue(widgets[[i]]) ) dump("draft","draft.R") cat("Draft dumped to draft.R\n") } ## A simple dialog aboutMail <- function(...) gmessage("Sends a message") ## Make main window from top down window <- gwindow("Compose mail", visible=FALSE) group <- ggroup(horizontal=FALSE, spacing=0, container = window) ## Remove border svalue(group) <- 0 actions <- list(save=gaction("Save", icon="save", handler=saveDraft), send=gaction("Send", icon="connect", handler=sendIt), quit=gaction("Quit", icon="quit", handler=function(...) dispose(window)), about=gaction("About", icon="about", handler=aboutMail)) ## Menubar is defined by the actions, but we nest under File menu menubarlist <- list(File=actions) gmenu(menubarlist, cont = window) ## Toolbar is also defined by the actions toolbarlist <- actions[-4] gtoolbar(toolbarlist, cont=window) ## Put headers in a glayout() container tbl <- glayout(container = group) ## To: field. Looks for buddyList tbl[1,1] <- glabel("To:", container = tbl) tbl[1,2] <- (widgets$to <- gcombobox(c(""), editable=TRUE, container=tbl, expand=TRUE)) size(widgets$to) <- c(300, -1) if(exists("buddyList")) widgets$to[] <- buddyList ## From: field. Click to edit value tbl[2,1] <- glabel("From:", container = tbl) tbl[2,2] <- (widgets$from <- glabel(FROM, editable=TRUE, container=tbl)) ## Subject: field. Handler updates window title tbl[3,1] <- glabel("Subject:", container=tbl) tbl[3,2] <- (widgets$subject <- gedit("",container=tbl)) addHandlerKeystroke(widgets$subject, handler = function(h,...) svalue(window) <- paste("Compose mail:",svalue(h$obj),collapse="")) ## Add text box for message, but first some space addSpace(group, 5) widgets$text <- gtext("", container = group, expand=TRUE) ## Handle drafts. Either a list or a filename to source") ## The generic svalue() method makes setting values easy") if(!is.null(draft)) { if(is.character(draft)) sys.source(draft,envir=environment()) # source into right enviro if(is.list(draft)) { sapply(c("to","from","subject","text"), function(i) { svalue(widgets[[i]]) <- draft[[i]] }) } } visible(window) <- TRUE ## That's it. } @ %%$ To compose an e-mail we call the function as follows. (The widget constructed looks like Figure~\ref{fig:Rmail}.) <>= Rmail() @ \begin{figure}[htbp] \centering \includegraphics[width=.5\textwidth]{Rmail} \caption{Widget for composing an e-mail message. (Needs a grammar checker.) } \label{fig:Rmail} \end{figure} The \RFunc{Rmail} function uses a few tricks. A combobox is used to hold the ``To:'' field. This is done so that a ``buddy list'' can be added if present. The \code{[<-} method for comboboxes make this straightforward. For widgets that have a collection of items to select from, the vector and matrix methods are defined to make changing values familiar to R users. (Although the use of the method \code{[<-} for \code{glayout} containers can cause confusion, as no \code{[} method exists due to the indexing referring to coordinates and not indexes.) The ``From:'' field uses an editable label. Clicking in the label's text allows its value to be changed. Just hit ENTER when done.~\footnote{Editable labels seemed like a good idea at the time -- they were borrowed from gmail's interface -- but in experience they seem to be confusing to users. YMMV.} The handler assigned to the ``Subject:'' field updates the window title every keystroke. The title of the window is updated with the windows \RFunc{svalue<-} method. The \RFunc{svalue} and \RFunc{svalue<-} methods are the work-horse methods of \code{gWidgets}. The are used to retrieve the selected value of a widget or set the selected value of a widget. One advantage to have a single generic function do this is illustrated in the handling of a draft: \begin{Soutput} sapply(c("to","from","subject","text"), function(i) svalue(widgets[[i]]) <- draft[[i]]) \end{Soutput} (Another work-horse method is \RFunc{addHandlerChanged} which can be used to add a handler to any widget, where ``changed'' -- being a generic function -- is loosely interpreted: i.e., for buttons, it is aliased to \RFunc{addHandlerClicked}. As for the \RFunc{sendIt} function, this is just one way to send an e-mail message on a UNIX machine. There are likely more than 100 different ways clever people could think of doing this task, most better than this one. To make portable code, when filling in the layout container, the widget constructors use the layout container as the parent container for the new widget. \section{An expanding group} As an example of the \code{add} and \code{delete} methods of a container, we show how one could create the \code{gexpandgroup} widget, were it not implemented by the underlying toolkit (eg. \pkg{gWidgetstcltk}). This container involves an icon to click on to show the container and a similar icon to hide the container. A label indicates to the user what is going on. <>= ## expand group rightArrow <- system.file("images/1rightarrow.gif",package="gWidgets") downArrow <- system.file("images/1downarrow.gif",package="gWidgets") g <- ggroup(horizontal=FALSE,cont=T) g1 <- ggroup(horizontal=TRUE, cont=g) icon <- gimage(downArrow,cont=g1) label <- glabel("Expand group example", cont=g1) g2 <- ggroup(cont=g, expand=TRUE) expandGroup <- function() add(g,g2, expand=TRUE) hideGroup <- function() delete(g,g2) state <- TRUE # a global changeState <- function(h,...) { if(state) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } state <<- !state } addHandlerClicked(icon, handler=changeState) addHandlerClicked(label, handler=changeState) gbutton("Hide by clicking arrow", cont=g2) @ %%>> As an alternative to using the global \code{state} variable, the \RFunc{tag} function could be used. This is like \RFunc{attr} only it stores the value with the widget -- not a copy -- so can be used within a handler to propogate changes outside the scope of the handler call. For instance, the \code{changeState} function could have been written as <<>>= tag(g,"state") <- TRUE # a global changeState <- function(h,...) { if(tag(g,"state")) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } tag(g,"state") <- !tag(g,"state") } @ Other alternatives to using global variables include using environments or the \pkg{proto} package for \code{proto} objects. These objects are passed not by copy, but by reference so changes within a function are reflected outside the scope of the function. \section{Drag and drop} GTK supports drag and drop features, and the \code{gWidgets} API provides a simple mechanism to add drag and drop to widgets. (Some widgets, such as text boxes, support drag and drop without these in GTK.) The basic approach is to add a drop source to the widget you wish to drag from, and add a drop target to the widget you want to drag to. You can also provide a handler to deal with motions over the drop target. See the man page \code{?gWidgetsRGtk-dnd} for more information. [In \pkg{gWidgetsQt} drag and drop support is very limited.] [In \pkg{gWidgetsrJava} drag and drop is provided through Java and not \pkg{gWidgets}. One can drag from widget to widget, but there is no way to configure what happens when a drop is made, or what is dragged when a drag is initiated.] [In \pkg{gWidgetstcltk} drag and drop works but not from other applications. ] We give two examples of drag and drop. One where variables from the variable browser are dropped onto a graph widget. Another illustrating drag and drop from the data frame editor to a widget. \subsection{DND with plots} This example shows the use of the plot device, the variable browser widget, and the use of the drag and drop features of gWidgets (Figure~\ref{fig:doPlot}). <<>>= doPlot <- function() { ## Set up main group mainGroup <- ggroup(container=gwindow("doPlot example")) ## The variable browser widget gvarbrowser(container = mainGroup) rightGroup <- ggroup(horizontal=FALSE, container=mainGroup) ## The graphics device ggraphics(container=rightGroup) entry <- gedit("drop item here to be plotted", container=rightGroup) adddroptarget(entry,handler = function(h,...) { do.call("plot",list(svalue(h$dropdata),main=id(h$dropdata))) }) } @ %%$ <>= doPlot() @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{doPlot.png} \caption{Dialog produced by \RFunc{doPlot} example} \label{fig:doPlot} \end{figure} The basic structure of using \code{gWidgets} is present in this example. The key widgets are the variable browser (\RFunc{gvarbrowser}), the plot device (\RFunc{ggraphics}), and the text-entry widget (\RFunc{gedit}). (One can see an \pkg{RGtk2} bias here, as the other implementations do not currently have an embeddable graphics device.) These are put into differing containers. Finally, there is an handler given to the result of the drag and drop. The \RFunc{do.call} line uses the \RFunc{svalue} and \RFunc{id} methods on a character, which in this instance returns the variable with that name and the name. To use this widget, one drags a variable to be plotted from the variable browser over to the area below the plot window. The \RFunc{plot} method is called on the values in the dropped variable. The \code{gvarbrowser} produces a widget from which a drop \textit{source} has been added. To drop from a different source the \code{addDropSource} method is used. The return value of the handler will be passed to the \code{dropdata} value of the handler for \code{addDropTarget}. [The latter varies from toolkit to toolkit, in \pkg{gWidgetsrJava} both are ignored, in RGtk2 some widgets have built-in drag and drop which can be overridden, and in \pkg{gWidgetstcltk} everything must be done using the \pkg{gWidgets} interface, as drag and drop is not naturally implemented by the toolkit.] %% \subsection{DND from the data frame editor} %% [This example applies only to \pkg{gWidgetsRGtk}, not %% \pkg{gWidgetsrJava} or \pkg{gWidgetstcltk}] %% The \RFunc{gdf} constructor makes a widget for editing data %% frames. The columns of which can be dropped onto a widget. This is %% done by dragging the column header. The code below also adds a handler %% so that changes to the column propagate to changes in the widget where %% the column is dropped. (Careful, this has some issues: the handler needs to %% be removed if the widget is closed.) %% <<>>= %% ## Drag a column onto plot to have a boxplot drawn. %% ## Changing the column values will redraw the graph. %% makeDynamicWidget <- function() { %% win <- gwindow("Draw a boxplot") %% gd <- ggraphics(container = win) %% adddroptarget(gd, targetType="object", handler=function(h,...) { %% tag(gd,"data") <- h$dropdata %% plotWidget(gd) %% ## this makes the dynamic part: %% ## - we put a change handler of the column that we get the data from %% ## - we store the handler id, so that we can clean up the handler when this %% ## window is closed %% ## The is.gdataframecolumn function checks if the drop value %% ## comes from the data frame editor (gdf) %% if(gWidgetsRGtk2:::is.gdataframecolumn(h$dropdata)) { %% view.col <- h$dropdata %% ## Put change handler on column to update plotting widget %% ## (use lower case, to fix oversight) %% id <- addhandlerchanged(view.col, handler=function(h,...) plotWidget(gd)) %% ## Save drop handler id so that it can be removed when %% ## widget is closed %% dropHandlers <- tag(gd,"dropHandlers") %% dropHandlers[[length(dropHandlers)+1]] <- %% list(view.col = view.col, %% id = id %% ) %% tag(gd,"dropHandlers") <- dropHandlers %% } %% }) %% ## Remove drop handlers if widget is unrealized. %% addHandlerUnrealize(gd, handler = function(h,...) { %% dropHandlers <- tag(gd,"dropHandlers") %% if(length(dropHandlers) > 0) { %% for(i in 1:length(dropHandlers)) { %% removehandler(dropHandlers[[i]]$view.col,dropHandlers[[i]]$id) %% } %% } %% }) %% } %% @ %% %% $ %% Next, we make the function that produces or updates the graphic. The %% data is stored in the tag-key "data". The use of \RFunc{id} and %% \RFunc{svalue} works for values which are either variable names or columns. %% <>= %% plotWidget <- function(widget) { %% data <- tag(widget, "data") %% theName <- id(data) %% values <- svalue(data) %% boxplot(values, xlab=theName, horizontal=TRUE, col=gray(.75)) %% } %% @ %% Now show the two widgets, the \RFunc{gdf} function constructs the data %% frame editor widget. %% <>= %% gdf(mtcars, container=TRUE) %% makeDynamicWidget() %% @ %% %%$ \section{Notebooks} The notebook is a common metaphor with computer applications, as they can give access to lots of information compactly on the screen. The \RFunc{gnotebook} constructor produces a notebook widget. New pages are added via the \RFunc{add} method (which is called behind the scenes when a widget is constructed), the current page is deleted through an icon [not implemented in \pkg{gWidgetsrJava}], or via the \RFunc{dispose} method, and vector methods are defined, such as \RFunc{names}, to make interacting with notebooks natural (the names refer to the tab labels.) One can also add pages when constructing a widget using the notebook as the container and passing in an extra argument \code{label}. The following example shows how a notebook can be used to organize different graphics devices. [In \pkg{gWidgetsRGtk2} the \RFunc{ggraphicsnotebook} function produces a similar widget. However, this is not possible if using \pkg{gWidgetsrJava}, as the graphic devices can't currently be embedded in a notebook page.] Our widget consists of a toolbar to add or delete plots and a notebook to hold the different graphics devices. The basic widgets are defined by the following: First we make window and group containers to hold our widgets and then a notebook instance. <<>>= win <- gwindow("Plot notebook") group <- ggroup(horizontal = FALSE, container=win) nb <- gnotebook(container = group, expand=TRUE) @ (\code{expand=TRUE} causes the child widget -- the notebook -- to expand to take as much space as allotted.) Next, we begin with an initial plot device. \begin{Soutput} > ggraphics(container = nb, label="plot") \end{Soutput} The \code{label} argument goes on the tab, as it is passed to the notebook's \code{add} method. Now we define and add a toolbar. <<>>= tblist <- list(quit=gaction("Quit", icon="quit", handler=function(...) dispose(win)), separator=gseparator(), new=gaction("New", icon="new", handler=function(h,...) add(nb,ggraphics(),label="plot")), delete=gaction("Delete", icond="delete", handler=function(...) dispose(nb)) ) gtoolbar(tblist, cont=group) @ The \RFunc{dispose} method is used both to close the window, and to close a tab on the notebook (the currently selected one). \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{notebook} \caption{Notebook widget for holding multiple plot devices provided by \RFunc{ggraphics}} \label{fig:notebook} \end{figure} That's it (Figure~\ref{fig:notebook}). There is one thing that should be added. If you switch tabs, the active device does not switch. This happens though if you click in the plot area. To remedy this, you can think about the \RFunc{addHandlerChanged} method for the notebook, or just use \RFunc{ggraphicsnotebook}. \section{The tree widget} The \RFunc{gtree} constructor [this widget is only implemented in \pkg{gWidgetsRGtk2}.] is used to present tree-like data. A familiar example of such data is the directory structure of your computer. To display a tree, \RFunc{gtree} needs to know what to display (the offspring) and which offspring have further offspring. idea of a node which consists of a path back to a root node. The offspring are determined by a function (\RFunc{offspring}) which takes the current path (ancestor information), and a passed in parameter as arguments. These offspring can either have subsequent offspring or not. This information must be known at the time of displaying the current offspring, and is answered by a function (\RFunc{hasOffspring}) which takes as an argument the offspring. In our file-system analogy, \RFunc{offspring} would list the files and directories in a given directory, and \RFunc{hasOffspring} would be \code{TRUE} for a directory in this listing, and \code{FALSE} for a file. For decorations, a function \RFunc{icon.FUN} can be given to decide what icon to draw for which listing. This should give a stock icon name. The data presented for the offspring is a data frame, with one column determining the path. This is typically the first column, but can be set with \RArg{chosencol}. \\ To illustrate, we create a file system browser using \RFunc{gtree}. (This is for UNIX systems. change the file separator for windows.) First to define the \RFunc{offspring} function we use the \RFunc{file.info} function. The current working directory is used as the base node for the tree: <<>>= ## function to find offspring offspring <- function(path, user.data=NULL) { if(length(path) > 0) directory <- paste(getwd(),"/",paste(path,sep="/", collapse=""),sep="",collapse="") else directory <- getwd() tmp <- file.info(dir(path=directory)) files <- data.frame(Name=rownames(tmp), isdir=tmp[,2], size=as.integer(tmp[,1])) return(files) } @ The offspring function is determined by the \code{isdir} column in the offspring data frame. <<>>= hasOffspring <- function(children,user.data=NULL, ...) { return(children$isdir) } @ Finally, an icon function can be given as follows, again using the \code{isdir} column. <<>>= icon.FUN <- function(children,user.data=NULL, ...) { x <- rep("file",length= nrow(children)) x[children$isdir] <- "directory" return(x) } @ The widget is then constructed as follows. See Figure~\ref{fig:filebrowser} for an example. <<>>= gtree(offspring, hasOffspring, icon.FUN = icon.FUN, container=gwindow(getwd())) @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{filebrowser} \caption{Illustration of a file browser using \RFunc{gtree} constructor.} \label{fig:filebrowser} \end{figure} The presence of the \code{isdir} column may bug some. It was convenient when defining \RFunc{hasOffspring} and \RFunc{icon.FUN}, but by then had served its purpose. One way to eliminate it, is to use the default for the \RArg{hasOffspring} argument which is to look for the second column of the data frame produced by \RFunc{offspring}. If this column is of class \code{logical}, it is used to define \RFunc{hasOffspring} and is then eliminated from the display. That is, the following would produce the desired file browser: <<>>= gtree(offspring, icon.FUN = icon.FUN, container=gwindow(getwd())) @ Finally, the \RArg{handler} argument (or \code{addHandlerDoubleclick}) could have been used to give an action to double clicking of an item in the tree. \section{Popup menus} A popup menu ``pops'' up a menu after a mouse click, typically a right mouse click. Implemented in \pkg{gWidgets} are the functions \begin{description} \item[\RFunc{add3rdmousepopupmenu}] for adding a popup on a right click \item[\RFunc{addpopupmenu}] for adding a popup on any click \end{description} The menu is specified using the syntax for \RFunc{gmenu}. \\ A simple example would be something like: <<>>= w <- gwindow("Click on button to change") g <- ggroup(cont = w) # abbreviate container glabel("Hello ", cont=g) world <- gbutton("world", cont=g) lst <- list() lst$world$handler <- function(h,...) svalue(world) <- "world" lst$continent$handler <- function(h,...) svalue(world) <- "continent" lst$country$handler <- function(h,...) svalue(world) <- "country" lst$state$handler <- function(h,...) svalue(world) <- "state" addPopupmenu(world, lst) @ Clicking on ``world'' with the mouse allows one to change the value in the label. \section{Defining layouts with \RFunc{gformlayout}} The \RFunc{gformlayout} constructor allows one to define the layout of a GUI using a list. The details of the list are in the man page, but the list has a relatively simple structure. Each widget is specified using a list. The widget type is specified through the \code{type} component as a string. These may be containers or widgets or the special container \code{fieldset}. For containers, the component \code{children} is used to specify the children to pack in. These again are specified using a list, and except for the \code{fieldset} container may again contain containers. The \code{name} argument is used to have the newly created component stored in a list of widgets for later manipulations. There are means to control whether a component is enabled or not based on a previously defined component, such as a checkbox. (This works much better under \pkg{gWidgetsRGtk2} than \pkg{gWidgetstcltk} as disabled parent containers do not disable their children in the latter.) This example comes from the man page. It shows how the ``fieldset'' container is used with some of its arguments to modify the number of columns and adjust the default label placements. We present the final list, \code{tTest} using some predefined lists that could be recycled for other GUIs if desired. <>= ## layout a collection of widgets to generate a t.test ## widgets to gather the variable(s) varList <- list(type="fieldset", columns = 2, label = "Variable(s)", label.pos = "top", label.font = c(weight="bold"), children = list( list(name = "x", label = "x", type = "gedit", text = ""), list(name = "y", label = "y", type = "gedit", text = "", depends.on = "x", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur" ) ) ) ## list for alternative altList <- list(type = "fieldset", label = "Hypotheses", columns = 2, children = list( list(name = "mu", type = "gedit", label = "Ho: mu=", text = "0", coerce.with = as.numeric), list(name = "alternative", type="gcombobox", label = "HA: ", items = c("two.sided","less","greater") ) ) ) ## now make t-test list tTest <- list(type = "ggroup", horizontal = FALSE, children = list( varList, altList, list(type = "fieldset", label = "two sample test", columns = 2, depends.on = "y", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur", children = list( list(name = "paired", label = "paired samples", type = "gcombobox", items = c(FALSE, TRUE) ), list(name = "var.equal", label = "assume equal var", type = "gcombobox", items = c(FALSE, TRUE) ) ) ), list(type = "fieldset", columns = 1, children = list( list(name = "conf.level", label = "confidence level", type = "gedit", text = "0.95", coerce.with = as.numeric) ) ) ) ) @ <>= ## Code to call the layout w <- gwindow("t.test") g <- ggroup(horizontal = FALSE, cont = w) fl <- gformlayout(tTest, cont = g, expand=TRUE) bg <- ggroup(cont = g) addSpring(bg) b <- gbutton("run t.test", cont = bg) addHandlerChanged(b, function(h,...) { out <- svalue(fl) out$x <- svalue(out$x) # turn text into numbers if(out$y == "") { out$y <- out$paired <- NULL } else { out$y <- svalue(out$y) } ## easy, not pretty print(do.call("t.test",out)) }) @ \section{Making widgets from an R function} A common task envisioned for \pkg{gWidgets} is to create GUIs that make collecting the arguments to a function easier to remember or enter. Presented below are two ways to do so without having to do any programming, provided you are content with the layout and features provided. \subsection{Using \RFunc{ggenericwidget}} \label{sec:using-ggenericwidget} The \RFunc{ggenericwidget} constructor maps a list into a widget. The list contains two types of information: meta information about the widget, such as the name of the function, and information about the widgets. This is specified using a list whose first component is the constructor, and subsequent components are fed to the constructor. To illustrate, a GUI for a one sample t-test is given. The list used by \RFunc{ggenericwidget} is defined below. <<>>= lst <- list() lst$title <- "t.test()" lst$help <- "t.test" lst$variableTypes <- "univariate" lst$action <- list(beginning="t.test(",ending=")") lst$arguments$hypotheses$mu <- list(type = "gedit",text=0,coerce.with=as.numeric) lst$arguments$hypotheses$alternative <- list(type="gradio", items=c("'two.sided'","'less'","'greater'") ) @ This list is then given to the constructor. <>= ggenericwidget(lst, container=gwindow("One sample t test")) @ Although this looks intimidating, due to the creation of the list, there is a function \RFunc{autogenerategeneric} that reduces the work involved. In particular, if the argument to \RFunc{ggenericwidget} is a character, then it is assumed to be the name of a function. From the arguments of this function, a layout is guessed. %% For example, we could have done: %% <>= %% our.t.test <- stats:::t.test.default %% ggenericwidget("our.t.test", container=gwindow("t-test")) %% @ %% As the arguments of this function are given by \code{args(out.t.test)} %% This widget has fields for selecting the alternative, the null, %% whether the data is paired, has equal variance assumption and a field %% to adjust the confidence level. \subsection{An alternative to \RFunc{ggenericwidget}} \label{sec:an-altern-ggenericwidget} This next example shows a different (although ultimately similar) way to produce a widget for a function. One of the points of this example is to illustrate the power of having common method names for the different widgets. Of course, the following can be improved. Two obvious places are the layout of the automagically generated widget, and and the handling of the initial variable when a formula is expected. <<>>= ## A constructor to automagically make a GUI for a function gfunction <- function(f, window = gwindow(title=fName), ...) { ## Get the function and its name if(is.character(f)) { fName <- f f <- get(f) } else if(is.function(f)) { fName <- deparse(substitute(f)) } ## Use formals() to define the widget lst <- formals(f) ## Hack to figure out variable type type <- NULL if(names(lst)[1] == "x" && names(lst)[2] == "y") { type <- "bivariate" } else if(names(lst)[1] == "x") { type <- "univariate" } else if(names(lst)[1] == "formula") { type <- "model" } else { type + NULL } ## Layout w <- gwindow("create dialog") g <- ggroup(horizontal = TRUE, cont=w) ## Arrange widgets with an output area ## Put widgets into a layout container tbl <- glayout(container=g) gseparator(horizontal=FALSE, container=g) outputArea <- gtext(container=g, expand=TRUE) ## Make widgets for arguments from formals() widgets <- sapply(lst, getWidget, cont=tbl) ## Layout widgets for( i in 1:length(widgets)) { tbl[i,1] <- names(lst)[i] tbl[i,2] <- widgets[[i]] } ## Add update handler to each widget when changed sapply(widgets, function(obj) { try(addHandlerChanged(obj, function(h,...) update()), silent=TRUE) }) ## Add drop target to each widget sapply(widgets, function(obj) try(adddroptarget(obj, handler=function(h,...) { svalue(h$obj) <- h$dropdata update() }), silent=TRUE)) ## In case this doesn't get exported svalue.default <- function(obj, ...) obj ## Function used to weed out 'NULL' values to widgets isNULL <- function(x) ifelse(class(x) == "character" && length(x) ==1 && x == "NULL", TRUE, FALSE) ## Function called when a widget is changed ## 2nd and 3rd lines trim out non-entries update <- function(...) { is.empty <- function(x) return(is.na(x) || is.null(x) || x == "" ) outList <- lapply(widgets,svalue) outList <- outList[!sapply(outList,is.empty)] outList <- outList[!sapply(outList,isNULL)] outList[[1]] <- svalue(outList[[1]]) if(type == "bivariate") outList[[2]] <- svalue(outList[[2]]) out <- capture.output(do.call(fName,outList)) dispose(outputArea) if(length(out)>0) add(outputArea, out) } invisible(NULL) } @ The \RFunc{getWidget} function takes a value from \RFunc{formals} and maps it to an appropriate widget. For arguments of type \code{call} the function recurses. <<>>= getWidget <- function(x, cont=cont) { switch(class(x), "numeric" = gedit(x, coerce.with=as.numeric, cont=cont), "character" = gcombobox(x, active=1, cont=cont), "logical" = gcombobox(c(TRUE,FALSE), active = 1 + (x == FALSE), cont=cont), "name" = gedit("", cont=cont), "NULL" = gedit("NULL", cont=cont), "call" = getWidget(eval(x), cont=cont), # recurse gedit("", cont=cont) # default ) } @ %% not there "list" = gListOfWidgets(x,name="", cont=cont), % This function defines a separate widget to handle the case where an % argument expects a list. It is written in the \code{gWidgetsRGtk} style % including an \RFunc{svalue} method below. The \RFunc{tag} method stores % a value in the widget, similar to setting an attribute. In this case, % the list of widgets stored is consulted by the following \RFunc{svalue} method. % <<>>= % gListOfWidgets = function(lst, name = "", container=NULL, ...) { % gp = gframe(text = name, container=container, horizontal=FALSE, ...) % obj = list(ref=gp) % class(obj) = c("gListOfWidgets") % tbl = glayout(container = gp) % widgetList = lapply(lst, getWidget, cont=tbl) % tag(obj, "widgetList") <- widgetList % ## pack into layout % for(i in 1:length(widgetList)) { % tbl[i,1] = names(widgetList)[i] % tbl[i,2] = widgetList[[i]] % } % visible(tbl) <- TRUE % return(obj) % } % @ % The methods below (\RFunc{svalue}, \RFunc{svalue<-} and % \RFunc{addHandlerChanged}) map the same method to each component % of the list using \RFunc{sapply}. % <<>>= % svalue.gListOfWidgets = function(obj, ...) { % lst = lapply(tag(obj, "widgetList"), svalue) % return(lst) % } % "svalue<-.gListOfWidgets" = function(obj, ..., value) { % if(!is.list(value)) % return(obj) % widgetList = getdata(obj, "widgetList") % sapply(names(value), function(x) svalue(widgetList[[x]]) <- value[[x]]) % return(obj) % } % addHandlerChanged.gListOfWidgets = function(obj, handler=NULL, action=NULL, ...) { % widgetList = getdata(obj, "widgetList") % sapply(widgetList, function(x) % try(addHandlerChanged(x, handler, action),silent=TRUE)) % } % @ We can try this out on the default \RFunc{t.test} function. First we grab a local copy from the namespace, then call our function. The widget with an initial value for \code{x} is shown in Figure~\ref{fig:gfunction}. %% <>= %% our.t.test <- stats:::t.test.default %% gfunction(our.t.test) %% @ \begin{figure}[htbp] \centering \includegraphics[width=.6\textwidth]{gfunction} \caption{Illustration of \RFunc{gfunction}} \label{fig:gfunction} \end{figure} \end{document} gWidgets/inst/doc/gWidgets.R0000644000176000001440000006571212377442527015531 0ustar ripleyusers### R code from vignette source 'gWidgets.Rnw' ################################################### ### code chunk number 1: gWidgets.Rnw:301-304 ################################################### require(gWidgets) ##options("guiToolkit"="RGtk2") options("guiToolkit"="tcltk") ################################################### ### code chunk number 2: gWidgets.Rnw:306-307 ################################################### require(gWidgetstcltk) ################################################### ### code chunk number 3: gWidgets.Rnw:352-353 ################################################### obj <- gbutton("Hello world", container = gwindow()) ################################################### ### code chunk number 4: gWidgets.Rnw:357-358 ################################################### obj <- glabel("Hello world", container = gwindow()) ################################################### ### code chunk number 5: gWidgets.Rnw:362-363 ################################################### obj <- gedit("Hello world", container = gwindow()) ################################################### ### code chunk number 6: gWidgets.Rnw:367-368 ################################################### obj <- gtext("Hello world", container = gwindow()) ################################################### ### code chunk number 7: gWidgets.Rnw:375-376 ################################################### obj <- gradio(c("hello","world"), container=gwindow()) ################################################### ### code chunk number 8: gWidgets.Rnw:382-383 ################################################### obj <- gcombobox(c("hello","world"), container=gwindow()) ################################################### ### code chunk number 9: gWidgets.Rnw:387-388 ################################################### obj <- gcombobox(c("hello","world"), editable=TRUE, container=gwindow()) ################################################### ### code chunk number 10: gWidgets.Rnw:393-394 ################################################### obj <- gtable(c("hello","world"), container=gwindow()) ################################################### ### code chunk number 11: gWidgets.Rnw:401-402 ################################################### obj <- gcheckboxgroup(c("hello","world"), container=gwindow()) ################################################### ### code chunk number 12: gWidgets.Rnw:409-413 ################################################### obj <- gslider(from=0, to = 7734, by =100, value=0, container=gwindow()) obj <- gspinbutton(from=0, to = 7734, by =100, value=0, container=gwindow()) ################################################### ### code chunk number 13: gWidgets.Rnw:426-435 ################################################### win <- gwindow("Hello World, ad nauseum", visible=TRUE) group <- ggroup(horizontal = FALSE, container=win) obj <- gbutton("Hello...",container=group, handler = function(h,...) gmessage("world")) obj <- glabel("Hello...", container =group, handler = function(h,...) gmessage("world")) obj <- gcombobox(c("Hello","world"), container=group) obj <- gedit("Hello world", container=group) obj <- gtext("Hello world", container=group, font.attr=list(style="bold")) ################################################### ### code chunk number 14: gWidgets.Rnw:507-526 ################################################### confirmDialog <- function(message, handler=NULL) { window <- gwindow("Confirm") group <- ggroup(container = window) gimage("info", dirname="stock", size="dialog", container=group) ## A group for the message and buttons inner.group <- ggroup(horizontal=FALSE, container = group) glabel(message, container=inner.group, expand=TRUE) ## A group to organize the buttons button.group <- ggroup(container = inner.group) ## Push buttons to right addSpring(button.group) gbutton("ok", handler=handler, container=button.group) gbutton("cancel", handler = function(h,...) dispose(window), container=button.group) return() } ################################################### ### code chunk number 15: gWidgets.Rnw:550-555 ################################################### confirmDialog("This space for rent", handler = function(h,...) { print("what to do... [Change accordingly]") ## In this instance dispose finds its parent window and closes it dispose(h$obj) }) ################################################### ### code chunk number 16: gWidgets.Rnw:567-575 ################################################### w <- gwindow("Two widgets") g <- ggroup(container = w) widget1 <- gbutton("Click me to update the counter", container=g, handler = function(h,...) { oldVal <- svalue(widget2) svalue(widget2) <- as.numeric(oldVal) + 1 }) widget2 <- glabel(0, container=g) ################################################### ### code chunk number 17: gWidgets.Rnw:622-629 ################################################### fileChoose <- function(action="print", text = "Select a file...", type="open", ...) { gfile(text=text, type=type, ..., action = action, handler = function(h,...) { do.call(h$action, list(h$file)) }) } ################################################### ### code chunk number 18: gWidgets.Rnw:662-670 ################################################### lstObjects <- function(envir= .GlobalEnv, pattern) { objlist <- ls(envir=envir, pattern=pattern) objclass <- sapply(objlist, function(objName) { obj <- get(objName, envir=envir) class(obj)[1] }) data.frame(Name = I(objlist), Class = I(objclass)) } ################################################### ### code chunk number 19: gWidgets.Rnw:677-681 ################################################### browseEnv1 <- function(envir = .GlobalEnv, pattern) { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv1")) } ################################################### ### code chunk number 20: gWidgets.Rnw:690-698 ################################################### browseEnv2 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container = gwindow("browseEnv2"), action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } ################################################### ### code chunk number 21: gWidgets.Rnw:704-714 ################################################### browseEnv3 <- function(envir = .GlobalEnv, pattern, action="summary") { listOfObjects <- lstObjects(envir=envir, pattern) gtable(listOfObjects, container =gwindow("browseEnv3"), filter.column = 2, action = action, handler = function(h,...) { print(do.call(h$action, list(get(svalue(h$obj))))) }) } ################################################### ### code chunk number 22: setUp (eval = FALSE) ################################################### ## ## set up ## availDists <- c(Normal="rnorm", Exponential="rexp") ## availKernels <- c("gaussian", "epanechnikov", "rectangular", ## "triangular", "biweight", "cosine", "optcosine") ################################################### ### code chunk number 23: updatePlot (eval = FALSE) ################################################### ## updatePlot <- function(h,...) { ## x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) ## plot(density(x, adjust = svalue(bandwidthAdjust), ## kernel = svalue(kernel)),main="Density plot") ## rug(x) ## } ################################################### ### code chunk number 24: define.widgets (eval = FALSE) ################################################### ## distribution <- gradio(names(availDists), horizontal=FALSE, handler=updatePlot) ## kernel <- gcombobox(availKernels, handler=updatePlot) ## bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, handler=updatePlot) ## sampleSize <- gradio(c(50,100,200, 300), handler = updatePlot) ################################################### ### code chunk number 25: layout (eval = FALSE) ################################################### ## ## now layout ## window <- gwindow("gWidgetsDensity") ## BigGroup <- ggroup(cont=window) ## ## group <- ggroup(horizontal=FALSE, container=BigGroup) ## tmp <- gframe("Distribution", container=group) ## add(tmp, distribution) ## ## tmp <- gframe("Sample size", container=group) ## add(tmp,sampleSize) ## ## tmp <- gframe("Kernel", container=group) ## add(tmp,kernel) ## ## tmp <- gframe("Bandwidth adjust", container=group) ## add(tmp,bandwidthAdjust, expand=TRUE) ################################################### ### code chunk number 26: add (eval = FALSE) ################################################### ## add(BigGroup, ggraphics()) ################################################### ### code chunk number 27: gwtkdensity ################################################### gwtkdensity <- function() { ## set up availDists <- c(Normal = "rnorm", Exponential="rexp") availKernels <- c("gaussian", "epanechnikov", "rectangular", "triangular", "biweight", "cosine", "optcosine") updatePlot <- function(h,...) { x <- do.call(availDists[svalue(distribution)],list(svalue(sampleSize))) plot(density(x, adjust = svalue(bandwidthAdjust), kernel = svalue(kernel))) rug(x) } ##The widgets win <- gwindow("gwtkdensity") gp <- ggroup(horizontal=FALSE, cont=win) tmp <- gframe("Distribution", container=gp, expand=TRUE) distribution <- gradio(names(availDists), horizontal=FALSE, cont=tmp, handler=updatePlot) tmp <- gframe("Sample size", container=gp, expand=TRUE) sampleSize <- gradio(c(50,100,200, 300), cont=tmp, handler =updatePlot) tmp <- gframe("Kernel", container=gp, expand=TRUE) kernel <- gcombobox(availKernels, cont=tmp, handler=updatePlot) tmp <- gframe("Bandwidth adjust", container=gp, expand=TRUE) bandwidthAdjust <- gslider(from=0,to=2,by=.01, value=1, cont=tmp, expand=TRUE, handler=updatePlot) } ################################################### ### code chunk number 28: buddyList ################################################### FROM <- "gWidgetsRGtk " buddyList <- c("My Friend ","My dog ") ################################################### ### code chunk number 29: Rmail ################################################### Rmail <- function(draft = NULL, ...) { ## We use a global list to contain our widgets widgets <- list() ## Helper functions sendIt <- function(...) { tmp <- tempfile() cat("To:", svalue(widgets$to),"\n",file = tmp, append=TRUE) cat("From:", svalue(widgets$from),"\n", file=tmp, append=TRUE) cat("Subject:", svalue(widgets$subject),"\n", file=tmp, append=TRUE) cat("Date:", format(Sys.time(),"%d %b %Y %T %Z"),"\n", file=tmp, append=TRUE) cat("X-sender:", "R", file=tmp, append=TRUE) cat("\n\n", file=tmp, append=TRUE) cat(svalue(widgets$text), file=tmp, append=TRUE) cat("\n", file=tmp, append=TRUE) ## Use UNIX sendmail to send message system(paste("sendmail -t <", tmp)) ## Add To: to buddyList if(exists("buddyList")) assign("buddyList", unique(c(buddyList,svalue(widgets$to))), inherits=TRUE) ## Close window, delete file unlink(tmp) dispose(window) } ## Function to save a draft to the file draft.R saveDraft <- function(...) { draft <- list() sapply(c("to","from","subject","text"), function(i) draft[[i]] <<- svalue(widgets[[i]]) ) dump("draft","draft.R") cat("Draft dumped to draft.R\n") } ## A simple dialog aboutMail <- function(...) gmessage("Sends a message") ## Make main window from top down window <- gwindow("Compose mail", visible=FALSE) group <- ggroup(horizontal=FALSE, spacing=0, container = window) ## Remove border svalue(group) <- 0 actions <- list(save=gaction("Save", icon="save", handler=saveDraft), send=gaction("Send", icon="connect", handler=sendIt), quit=gaction("Quit", icon="quit", handler=function(...) dispose(window)), about=gaction("About", icon="about", handler=aboutMail)) ## Menubar is defined by the actions, but we nest under File menu menubarlist <- list(File=actions) gmenu(menubarlist, cont = window) ## Toolbar is also defined by the actions toolbarlist <- actions[-4] gtoolbar(toolbarlist, cont=window) ## Put headers in a glayout() container tbl <- glayout(container = group) ## To: field. Looks for buddyList tbl[1,1] <- glabel("To:", container = tbl) tbl[1,2] <- (widgets$to <- gcombobox(c(""), editable=TRUE, container=tbl, expand=TRUE)) size(widgets$to) <- c(300, -1) if(exists("buddyList")) widgets$to[] <- buddyList ## From: field. Click to edit value tbl[2,1] <- glabel("From:", container = tbl) tbl[2,2] <- (widgets$from <- glabel(FROM, editable=TRUE, container=tbl)) ## Subject: field. Handler updates window title tbl[3,1] <- glabel("Subject:", container=tbl) tbl[3,2] <- (widgets$subject <- gedit("",container=tbl)) addHandlerKeystroke(widgets$subject, handler = function(h,...) svalue(window) <- paste("Compose mail:",svalue(h$obj),collapse="")) ## Add text box for message, but first some space addSpace(group, 5) widgets$text <- gtext("", container = group, expand=TRUE) ## Handle drafts. Either a list or a filename to source") ## The generic svalue() method makes setting values easy") if(!is.null(draft)) { if(is.character(draft)) sys.source(draft,envir=environment()) # source into right enviro if(is.list(draft)) { sapply(c("to","from","subject","text"), function(i) { svalue(widgets[[i]]) <- draft[[i]] }) } } visible(window) <- TRUE ## That's it. } ################################################### ### code chunk number 30: comd (eval = FALSE) ################################################### ## Rmail() ################################################### ### code chunk number 31: expandgroup ################################################### ## expand group rightArrow <- system.file("images/1rightarrow.gif",package="gWidgets") downArrow <- system.file("images/1downarrow.gif",package="gWidgets") g <- ggroup(horizontal=FALSE,cont=T) g1 <- ggroup(horizontal=TRUE, cont=g) icon <- gimage(downArrow,cont=g1) label <- glabel("Expand group example", cont=g1) g2 <- ggroup(cont=g, expand=TRUE) expandGroup <- function() add(g,g2, expand=TRUE) hideGroup <- function() delete(g,g2) state <- TRUE # a global changeState <- function(h,...) { if(state) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } state <<- !state } addHandlerClicked(icon, handler=changeState) addHandlerClicked(label, handler=changeState) gbutton("Hide by clicking arrow", cont=g2) ################################################### ### code chunk number 32: gWidgets.Rnw:1129-1140 ################################################### tag(g,"state") <- TRUE # a global changeState <- function(h,...) { if(tag(g,"state")) { hideGroup() svalue(icon) <- rightArrow } else { expandGroup() svalue(icon) <- downArrow } tag(g,"state") <- !tag(g,"state") } ################################################### ### code chunk number 33: gWidgets.Rnw:1183-1199 ################################################### doPlot <- function() { ## Set up main group mainGroup <- ggroup(container=gwindow("doPlot example")) ## The variable browser widget gvarbrowser(container = mainGroup) rightGroup <- ggroup(horizontal=FALSE, container=mainGroup) ## The graphics device ggraphics(container=rightGroup) entry <- gedit("drop item here to be plotted", container=rightGroup) adddroptarget(entry,handler = function(h,...) { do.call("plot",list(svalue(h$dropdata),main=id(h$dropdata))) }) } ################################################### ### code chunk number 34: gWidgets.Rnw:1202-1203 (eval = FALSE) ################################################### ## doPlot() ################################################### ### code chunk number 35: gWidgets.Rnw:1358-1361 ################################################### win <- gwindow("Plot notebook") group <- ggroup(horizontal = FALSE, container=win) nb <- gnotebook(container = group, expand=TRUE) ################################################### ### code chunk number 36: gWidgets.Rnw:1376-1383 ################################################### tblist <- list(quit=gaction("Quit", icon="quit", handler=function(...) dispose(win)), separator=gseparator(), new=gaction("New", icon="new", handler=function(h,...) add(nb,ggraphics(),label="plot")), delete=gaction("Delete", icond="delete", handler=function(...) dispose(nb)) ) gtoolbar(tblist, cont=group) ################################################### ### code chunk number 37: gWidgets.Rnw:1439-1449 ################################################### ## function to find offspring offspring <- function(path, user.data=NULL) { if(length(path) > 0) directory <- paste(getwd(),"/",paste(path,sep="/", collapse=""),sep="",collapse="") else directory <- getwd() tmp <- file.info(dir(path=directory)) files <- data.frame(Name=rownames(tmp), isdir=tmp[,2], size=as.integer(tmp[,1])) return(files) } ################################################### ### code chunk number 38: gWidgets.Rnw:1454-1457 ################################################### hasOffspring <- function(children,user.data=NULL, ...) { return(children$isdir) } ################################################### ### code chunk number 39: gWidgets.Rnw:1463-1468 ################################################### icon.FUN <- function(children,user.data=NULL, ...) { x <- rep("file",length= nrow(children)) x[children$isdir] <- "directory" return(x) } ################################################### ### code chunk number 40: gWidgets.Rnw:1473-1475 ################################################### gtree(offspring, hasOffspring, icon.FUN = icon.FUN, container=gwindow(getwd())) ################################################### ### code chunk number 41: gWidgets.Rnw:1495-1497 ################################################### gtree(offspring, icon.FUN = icon.FUN, container=gwindow(getwd())) ################################################### ### code chunk number 42: gWidgets.Rnw:1522-1532 ################################################### w <- gwindow("Click on button to change") g <- ggroup(cont = w) # abbreviate container glabel("Hello ", cont=g) world <- gbutton("world", cont=g) lst <- list() lst$world$handler <- function(h,...) svalue(world) <- "world" lst$continent$handler <- function(h,...) svalue(world) <- "continent" lst$country$handler <- function(h,...) svalue(world) <- "country" lst$state$handler <- function(h,...) svalue(world) <- "state" addPopupmenu(world, lst) ################################################### ### code chunk number 43: t-test-ex ################################################### ## layout a collection of widgets to generate a t.test ## widgets to gather the variable(s) varList <- list(type="fieldset", columns = 2, label = "Variable(s)", label.pos = "top", label.font = c(weight="bold"), children = list( list(name = "x", label = "x", type = "gedit", text = ""), list(name = "y", label = "y", type = "gedit", text = "", depends.on = "x", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur" ) ) ) ## list for alternative altList <- list(type = "fieldset", label = "Hypotheses", columns = 2, children = list( list(name = "mu", type = "gedit", label = "Ho: mu=", text = "0", coerce.with = as.numeric), list(name = "alternative", type="gcombobox", label = "HA: ", items = c("two.sided","less","greater") ) ) ) ## now make t-test list tTest <- list(type = "ggroup", horizontal = FALSE, children = list( varList, altList, list(type = "fieldset", label = "two sample test", columns = 2, depends.on = "y", depends.FUN = function(value) nchar(value) > 0, depends.signal = "addHandlerBlur", children = list( list(name = "paired", label = "paired samples", type = "gcombobox", items = c(FALSE, TRUE) ), list(name = "var.equal", label = "assume equal var", type = "gcombobox", items = c(FALSE, TRUE) ) ) ), list(type = "fieldset", columns = 1, children = list( list(name = "conf.level", label = "confidence level", type = "gedit", text = "0.95", coerce.with = as.numeric) ) ) ) ) ################################################### ### code chunk number 44: dontshow (eval = FALSE) ################################################### ## ## Code to call the layout ## w <- gwindow("t.test") ## g <- ggroup(horizontal = FALSE, cont = w) ## fl <- gformlayout(tTest, cont = g, expand=TRUE) ## bg <- ggroup(cont = g) ## addSpring(bg) ## b <- gbutton("run t.test", cont = bg) ## addHandlerChanged(b, function(h,...) { ## out <- svalue(fl) ## out$x <- svalue(out$x) # turn text into numbers ## if(out$y == "") { ## out$y <- out$paired <- NULL ## } else { ## out$y <- svalue(out$y) ## } ## ## easy, not pretty ## print(do.call("t.test",out)) ## }) ## ################################################### ### code chunk number 45: gWidgets.Rnw:1687-1697 ################################################### lst <- list() lst$title <- "t.test()" lst$help <- "t.test" lst$variableTypes <- "univariate" lst$action <- list(beginning="t.test(",ending=")") lst$arguments$hypotheses$mu <- list(type = "gedit",text=0,coerce.with=as.numeric) lst$arguments$hypotheses$alternative <- list(type="gradio", items=c("'two.sided'","'less'","'greater'") ) ################################################### ### code chunk number 46: ggenericw (eval = FALSE) ################################################### ## ggenericwidget(lst, container=gwindow("One sample t test")) ################################################### ### code chunk number 47: gWidgets.Rnw:1733-1826 ################################################### ## A constructor to automagically make a GUI for a function gfunction <- function(f, window = gwindow(title=fName), ...) { ## Get the function and its name if(is.character(f)) { fName <- f f <- get(f) } else if(is.function(f)) { fName <- deparse(substitute(f)) } ## Use formals() to define the widget lst <- formals(f) ## Hack to figure out variable type type <- NULL if(names(lst)[1] == "x" && names(lst)[2] == "y") { type <- "bivariate" } else if(names(lst)[1] == "x") { type <- "univariate" } else if(names(lst)[1] == "formula") { type <- "model" } else { type + NULL } ## Layout w <- gwindow("create dialog") g <- ggroup(horizontal = TRUE, cont=w) ## Arrange widgets with an output area ## Put widgets into a layout container tbl <- glayout(container=g) gseparator(horizontal=FALSE, container=g) outputArea <- gtext(container=g, expand=TRUE) ## Make widgets for arguments from formals() widgets <- sapply(lst, getWidget, cont=tbl) ## Layout widgets for( i in 1:length(widgets)) { tbl[i,1] <- names(lst)[i] tbl[i,2] <- widgets[[i]] } ## Add update handler to each widget when changed sapply(widgets, function(obj) { try(addHandlerChanged(obj, function(h,...) update()), silent=TRUE) }) ## Add drop target to each widget sapply(widgets, function(obj) try(adddroptarget(obj, handler=function(h,...) { svalue(h$obj) <- h$dropdata update() }), silent=TRUE)) ## In case this doesn't get exported svalue.default <- function(obj, ...) obj ## Function used to weed out 'NULL' values to widgets isNULL <- function(x) ifelse(class(x) == "character" && length(x) ==1 && x == "NULL", TRUE, FALSE) ## Function called when a widget is changed ## 2nd and 3rd lines trim out non-entries update <- function(...) { is.empty <- function(x) return(is.na(x) || is.null(x) || x == "" ) outList <- lapply(widgets,svalue) outList <- outList[!sapply(outList,is.empty)] outList <- outList[!sapply(outList,isNULL)] outList[[1]] <- svalue(outList[[1]]) if(type == "bivariate") outList[[2]] <- svalue(outList[[2]]) out <- capture.output(do.call(fName,outList)) dispose(outputArea) if(length(out)>0) add(outputArea, out) } invisible(NULL) } ################################################### ### code chunk number 48: gWidgets.Rnw:1833-1844 ################################################### getWidget <- function(x, cont=cont) { switch(class(x), "numeric" = gedit(x, coerce.with=as.numeric, cont=cont), "character" = gcombobox(x, active=1, cont=cont), "logical" = gcombobox(c(TRUE,FALSE), active = 1 + (x == FALSE), cont=cont), "name" = gedit("", cont=cont), "NULL" = gedit("NULL", cont=cont), "call" = getWidget(eval(x), cont=cont), # recurse gedit("", cont=cont) # default ) } gWidgets/inst/doc/addingToolkit.Rnw0000644000176000001440000003143612377442527017111 0ustar ripleyusers\documentclass[12pt]{article} \newcommand{\VERSION}{0.0-2} %\VignetteIndexEntry{addingToolkit} %\VignettePackage{addingToolkit} \usepackage{times} % for fonts \usepackage[]{geometry} \usepackage{mathptm} % for math fonts type 1 \usepackage{graphicx} % for graphics files %%\usepackage{floatflt} % for ``floating boxes'' %%\usepackage{index} %%\usepackage{relsize} % for relative size fonts \usepackage{amsmath} % for amslatex stuff \usepackage{amsfonts} % for amsfonts \usepackage{url} % for \url, \usepackage{color} %%\usepackage{fancyvrb} %%\usepackage{fancyhdr} %%\usepackage{jvfloatstyle} % redefine float.sty for my style. Hack %% squeeze in stuff %%\floatstyle{jvstyle} %%\restylefloat{table} %%\restylefloat{figure} %%\renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} %% Fill these in % \pagestyle{fancy} % \usepackage{fancyhdr} % \pagestyle{fancy} % \fancyhf{} % \fancyhead[L]{\RCode{gWidgets}} % \fancyhead[C]{} % \fancyhead[R]{\sectionmark} % \fancyfoot[L]{} % \fancyfoot[C]{- page \thepage\/ -} % \fancyfoot[R]{} % \renewcommand{\headrulewidth}{0.1pt} % \renewcommand{\footrulewidth}{0.0pt} %% My abbreviations \newcommand{\RCode}[1]{\texttt{#1}} \newcommand{\RFunc}[1]{\texttt{#1()}} \newcommand{\RPackage}[1]{\textbf{#1}} \newcommand{\RArg}[1]{\texttt{#1=}} \newcommand{\RListel}[1]{\texttt{\$#1}} \newenvironment{RArgs}{\begin{list}{}{}}{\end{list}} \begin{document} \thispagestyle{plain} \title{Adding a toolkit to gWidgets} \author{John Verzani, \url{gWidgetsRGtk@gmail.com}} \maketitle \section*{Abstract:} [\textbf{This package is now out of date. The \RPackage{gWidgetstcltk} package has been written. This is here in case someone wants to port a different toolkit (RwxWidgets say).}] \\ This little vignette illustrates what is required to write a toolkit for the \RPackage{gWidgets} package. Since the \RPackage{gWidgetsRGtk} package is written this sketches out what a toolkit would possibly look like using the \RPackage{tcltk} package. \setcounter{tocdepth}{3} \tableofcontents \section{Basics of gWidgets} The gWidgets implementation is simply a set of functions that dispatch to similarly named functions in a toolkit. That is the \RCode{glabel(...,toolkit=guiToolkit())} function dispatches to the \RCode{.glabel(toolkit, ...)} function in the appropriate toolkit, and the \RCode{svalue(obj,...)} method dispatches to the \RCode{.svalue(obj@widget,obj@toolkit, ...)} function in the appropriate toolkit. In the first case, a constructor, the dispatch is done by the class of the toolkit. For the method, the dispatch is based on both the toolkit and the class of the object, and perhaps other arguments in the signature of the method. The classes for the toolkits \RCode{RGtk2}, \RCode{tcltk}, \RCode{rJava}, and \RCode{SJava} are already defined by gWidgets. These are named \RCode{guiWidgetsToolkit} plus the package name. As such, the basic structure of a gWidgets implementation is to set up some classes, and a set of methods for dispatch.~\footnote{Although it likely wasn't necessary, at the time of first writing a package, the dispatch was to a "dot" file. This caused an extra level to the dispatch, that while unfortunate, does not seem to be worth rewriting to avoid.} \section{An example} This shows some of what is necessary to write an implementation of gWidgets for the \RPackage{tcltk} package. It only assumes as much about \RPackage{tcltk} as was learned by browsing Peter Dalgaard's informative RNews article and a quick glance at the examples provided by James Wettenhall. First we load the package. \begin{Scode} ## load toolkit options("guiToolkit"=NA) library(gWidgets) library(tcltk) \end{Scode} The options setting ensures no toolkit for gWidgets gets loaded. We note the subclass of \RCode{guiWidgetsToolkit}, \RCode{guiWidgetsToolkittcltk} is already defined in \RCode{gWidgets}. Now we make a base class for the tcltk widgets created here. \begin{Scode} ## some classes setClass("gWidgetTcltk") ## A virtual class to hold tcltk object or guiWidget or gWidgetTcltk setClass("guiWidgetORgWidgetTcltkORtcltk") setIs("guiWidget","guiWidgetORgWidgetTcltkORtcltk") setIs("gWidgetTcltk","guiWidgetORgWidgetTcltkORtcltk") \end{Scode} Finally, we promote the \RCode{tkwin} class to an S4 class and add it to our virtual class. This would be done for all possible classes of \RCode{tcltk} objects. \begin{Scode} oldclasses = c("tkwin") for(i in oldclasses) { setOldClass(i) setIs(i,"guiWidgetORgWidgetTcltkORtcltk") } \end{Scode} The \RCode{gWidgetTcltk} class is a virtual class, here are two subclasses. We create slots for the widget and the toolkit here, but perhaps should add others such as an ID slot for storing a unique ID per widget. \begin{Scode} ### Make some base classes setClass("gComponentTcltk", representation( widget="guiWidgetORgWidgetTcltkORtcltk", toolkit="guiWidgetsToolkit" ), contains="gWidgetTcltk", ) setClass("gContainerTcltk", representation( widget="guiWidgetORgWidgetTcltkORtcltk", toolkit="guiWidgetsToolkit" ), contains="gWidgetTcltk", ) \end{Scode} Now we define some necessary functions to implement \RFunc{gwindow} in the toolkit. This involves defining a class, making a constructor (\RFunc{.gwindow}) and defining some methods. \begin{Scode} ## top level window setClass("gWindowTcltk", contains="gContainerTcltk", prototype=prototype(new("gContainerTcltk")) ) \end{Scode} This implementation of the constructor should have a handler for the window destroy event. \begin{Scode} setMethod(".gwindow", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, title="Window", visible=TRUE, handler=NULL, action = NULL, ... ) { win <- tktoplevel() tktitle(win) <- title obj = new("gWindowTcltk", widget=win, toolkit=toolkit) return(obj) }) \end{Scode} The \RFunc{svalue} method for \RFunc{gwindow} objects is used to retrieve and set the title of the window. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ..) { tktitle(obj@widget) }) setMethod(".svalue<-", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, index=NULL,..., value) { ## set the title tktitle(obj@widget) <- value return(obj) }) \end{Scode} The \RFunc{add} method is used to add a widget to a container. This is where we run into problems with \RPackage{tcltk} as the constructors there require a ``parent'' container at the time of construction. As such, we don't have both a container (\RCode{obj} below) and widget (\RCode{value}) needed when we add, rather we only specify how things are packed in. \begin{Scode} setMethod(".add", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk", value="guiWidget"), function(obj, toolkit, value, ...) { ## how to add? tkpack(value@widget@widget) }) \end{Scode} [To avoid this, the \RPackage{gWidgetstcltk} package requires a container be specified when a widget is constructed. This container stores the top-level container so that a \RPackage{tcltk} widget can be constructed. The \RCode{add} method is then rarely used publicly, but is useful when writing the constructor. It's arguments for placement of the widget are specified during the construction of the widget.] The \RCode{dispose} method closes the window \begin{Scode} setMethod(".dispose", signature(toolkit="guiWidgetsToolkittcltk",obj="gWindowTcltk"), function(obj, toolkit, ...) { tkdestroy(obj@widget) }) \end{Scode} Below we implement the basics of \RFunc{glabel}. No attempt is made to add a click handler to this or editing or markup. For now, just setting of text in a label. First a class \begin{Scode} ########### ## label class setClass("gLabelTcltk", contains="gComponentTcltk", prototype=prototype(new("gComponentTcltk")) ) \end{Scode} Next the constructor \begin{Scode} ## constructor setMethod(".glabel", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, text= "", markup = FALSE, editable = FALSE, handler = NULL, action = NULL, container = NULL, ... ) { ## if container is non null, we can evaluate expression if(is.null(container)) { cat("Can't have an NULL container with tcltk") } ## find tk container if(is(container,"guiWidget")) container=container@widget if(is(container,"gContainerTcltk")) container=container@widget label = tklabel(container, text=text) obj = new("gLabelTcltk",widget=label, toolkit=toolkit) ## pack into container tkpack(label) ## add callback ## no callbacks for labels return(obj) }) \end{Scode} The \RFunc{svalue} method returns the label text, it requires a little tcltk voodoo. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gLabelTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ..) { as.character(tkcget(obj@widget,"-text")) }) ## svalue<- setReplaceMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gLabelTcltk"), function(obj, toolkit, index=NULL, ..., value) { ## set the text tkconfigure(obj@widget, text=value) return(obj) }) \end{Scode} For the \RFunc{gbutton} implementation we show how to add a handler in addition to implementing the \RFunc{svalue<-} method. \begin{Scode} ### button class setClass("gButtonTcltk", contains="gComponentTcltk", prototype=prototype(new("gComponentTcltk")) ) \end{Scode} As for the constructor we have: \begin{Scode} setMethod(".gbutton", signature(toolkit="guiWidgetsToolkittcltk"), function(toolkit, text="", border=TRUE, handler=NULL, action=NULL, container=NULL,... ) { if(!is.null(container)) { topwin = container@widget@widget } else { topwin = gwindow(toolkit=toolkit)@widget } button = tkbutton(topwin, text=text) obj = new("gButtonTcltk",widget=button, toolkit=toolkit) tkpack(obj@widget) if(!is.null(handler)) .addhandlerclicked(obj, toolkit, handler=handler) return(obj) }) \end{Scode} In dealing with the handler, we used the private method defined below, rather than \RFunc{addHandlerClicked} as that method is for objects of class \RCode{guiWidget}, and not \RCode{gWidgetTcltk}. This awkwardness can be avoided by defining a method \RCode{addHandlerClicked} for objects of class \RCode{gWidgetTcltk} within the toolkit.~\footnote{This is a result of the way dispatch was designed. The toolkit information is stored in a slot separate from the widget provided by the toolkit in the gWidget object. Dispatch occurs on both the object and the toolkit. The method with these signatures is the ``dot'' one implemented in the toolkit package.} For instance, \begin{Scode} setMethod("addHandlerClicked",signature(obj="gWidgetTcltk"), function(obj, handler=NULL, action=NULL, ...) { .addhandlerclicked(obj, obj@toolkit,handler, action, ...) }) \end{Scode} (The internal function, \RCode{.addhandlerclicked}, uses lower case letters for now.) The handler could be written as follows \begin{Scode} setMethod(".addhandlerclicked", signature(toolkit="guiWidgetsToolkittcltk",obj="gWidgettcltk"), function(obj, toolkit, handler, action=NULL, ...) { tkbind(getWidget(obj),, function(...) { h = list(ref=obj, obj=obj, action=action) handler(h,...) }) }) \end{Scode} Again, \RFunc{svalue} should retrieve the text and \RFunc{svalue<-} should set the text. Again, a little tcltk voodoo is used. \begin{Scode} setMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gButtonTcltk"), function(obj, toolkit, index=NULL, drop=NULL, ...) { val = paste(as.character(tkcget(obj@widget,"-text"))) return(val) }) setReplaceMethod(".svalue", signature(toolkit="guiWidgetsToolkittcltk",obj="gButtonTcltk"), function(obj, toolkit, index=NULL, ..., value) { tkconfigure(obj@widget, text=value) return(obj) }) \end{Scode} \begin{figure}[htbp] \centering \includegraphics[width=.4\textwidth]{helloWorld} \caption{Hello world, how are you?} \label{fig:hello-world} \end{figure} Well, that will let us make the following simple dialog (Figure~\ref{fig:hello-world}). \begin{Scode} guitoolkit = new("guiWidgetsToolkittcltk") win = gwindow("Hello world", toolkit=guitoolkit) label=glabel("Hello world, how are you?", container=win, toolkit=guitoolkit) button=gbutton("Close", handler=function(h,...) dispose(win), container=win, toolkit=guitoolkit) \end{Scode} \end{document} gWidgets/inst/doc/gWidgets.pdf0000644000176000001440000155276112377442527016107 0ustar ripleyusers%PDF-1.5 % 107 0 obj << /Length 2058 /Filter /FlateDecode >> stream xYKs6WHɞvL|JL-Qz8l7.@ә(X~eU%oNG޿O^.L"3a4|JeXe||N_5z ?lf*- rF;_.$Bi+qSY *#|`ҤJ ģȴa(t :,s++q Rt!*S,gwB|wXNE*gPMn6}2r}%n2VhW7WБ''NrmY6ѕe,Y$՗Ƀ&Z%I>'L'ʖn,k )s)+ b`[e  r\P7 @"Nm&#!@Gۣ`J-뵘"քlY [_!%JBʴZ*gޒ5Ԫj kv:CX=5Kن*5}GHV_yXБ_=Y2:'n,#emo#d-eR~…'\ ءJ&Vc cńwP~KE݇`s8:'>]R׺(]Ҳ<oQd B0<}s`s)hVP#< QӞ1l 7OQ1Z ="PeR z8LmF:m =S}` !);'{bCF0p C#SOGYHMVnԐ mgxfX8/>rզqþﴣD n܇/EzT+ ./^]eqv0l751;=mX&|87} nuMb?sj'P9)fVY}/Ɍ}aؐ6@e%t-z`nH`nq' J1g`n"EN챥*Sy/({a-c2<~ıPq{\_a<|_ X֞0\4k޺}{g[Ƥt?sd* Wp 9y ;< _8Nu8`VkE^񞝧=n=fVq o򚮏gBWWƈ=AJ= O>M9'~FJePYbq7y jb)F\f8K SsI}_eF ]x[~P29ϗMkISb1K-]Y& [™vH-gZ%ӏe8=QjLt-);Cmb"7/KF e(Ew>lDD窑2~O,kU;Jde7$+2QWh*Q')F?q+_9d`q嬼Nv :p&Ov7Ts1LR:g[ v/||Q<x׍A/Y)` a gU_;^TT!!X~ݔЎ]"PĒX|BbAu!ۑޝжǍ: gXG10n?9;l9pq8K-{=pbO\//&s3iE0PE&`ځkN Q+ vBA^r¢LR &sm=p!ӎ;Y]U4ۖ /{stKLuP"АKd^O2$ endstream endobj 120 0 obj << /Length 3023 /Filter /FlateDecode >> stream xڕZIwFW6{&^%'ggO'Q&$)Z 4Sk% 赺֯O֓|E.o^|:5Ea'WIc:7.< ktOR>gމfoEEĂk;!8y (#'>VM:պMD'\>&] L;7}+f"31+=ik඼O`ҡ \STKĕ W5'4 SW6Yc3c[ g@784d*˱#+ef-Nt OXg\.0gMëpl/Q&ݽmt !G3z%<iIބXN_/E͛eN2#%cLl 7-DnsoH p [t+Ʋ UX)uχyů!#݈3)uSBѝܳ?qLT!nz$yzM|5}Tq^Q\wk~GN Ͳ,Y_02VX ũ^\iQ<]ԓ wߢ_ }s# >#kqvwcG#a`%j"0ء P*g8@$>‘'!5k.3ۛXs=MELq[IYnˉϜW:$|!|>Ҭ#ez~/A'9qM!җ@aV1cI6SF)pUjUlvy䋜z MNagոBuw`_ѐ2X\h"m6<3 ui Kd o@f-ICfؐd5rL8~uxsPIgnWBt7`DB5b*4>e\oFH] J >MZ%o+j )ŖEV 볝FVā Sq粪v_@:Az.@OC"<Ƚ1PnyRgO0+D4S""H?N =0n%V-Ucu ݝ sgSiИGL3T;` ze?AJ5JB{ud'ɓ )GW #mq-#Mz?I[$a7 J)V?͜e@qBl@k!?@MJL{mQ f^*Y< Nӆ銄հ2}iEI=iabasEPKjoO\X-?i-5EAH}D`hyd u8pDnUU~8 ZﲊJaiK*c(k_4n'4nh%n%=E EAnpʦL>AX{ >t”H4Z2 >O mEBz]}DK,MLSׂ!J˅|rKiͺѮdB!)H Sm[&Xid(UpN^+(ʢ,^g>YB4siNȆ//~lWL #OYaΌ9)N +ee k?"O=T.0 y*}ZA`R1F y,L$%̳|prS> stream xڥˎ>_asd d@000ܶH%~In3dbXwvN?çtbLR繝,6։+&E'iM/nflz%<~V5<[q$`p3[MB5 AVv~͋<;]fs[0^];HZPm}鷔Sѯ'Mg^c27e5$ R.O lMNA]+=uVdoز- D !>,tgBcK >Tӥ,,2sO! A"=Z8vG|JcE6=! Ui7Ei.Ppxe6 -7܊¢b NTVI!5NEoah.nYFr V5's[U{Zo-r YQ+!\p:K> 7z-0|P Fpm%JgkCjʀd"93ĚgslP=I%մ3f꾜˦o H;^ |?3QN8sN!O "Os$o1+֟{Tv @|^DD.`ݘ,:ɮ7r$|T O0Vg G Iy]һk<]aCKk-=A&J2\.1.Fa:˞YD[Np+q6zǻ7wwcyXkTrd zG4*փw͒6qX@1W},jr.Vl)EüTƒl 4ѹʽ%JIz,R-fax&xuSw֯,ӮE(E^xMe6J1rtM)xʱ̾!ӏrq#|TǀéĚ<#l@xuÐn67f/HQNIߋՎ AĂ◌NHWfb~ֻvsBPiT?ʪՐ eSS{y{H)x_34euA<υq(:T;uE5OuGM(܍n\޳2S;&*[$Ϯlv('- ^ D|R<s,s H] A/ 47Q?3IQz׿S?~>r! zTDžN$,2K29Iډ,:c _`:T)/ߥPrVuA#/PBH7#gPTa@'mn%n^F%Xf27$T7^>JS/k׏r+ /Lԙfн{ i<^}C2R=ߨ>ˁV^?&Rxz+?7uu?'V7ª%l^ui! 4k;UP~GcgƐ*ny)}y7mMƠ;KU=]_I{R ʹ/zwz;D? $[)Yqbbu(s糜%ʰ/4- . Pa=lGFWyUU+ra8Db㓇ay1V5vCkrI4MPtjGZ3ϓB)%x@2ZK#󵥈U53gIG 1e\_T뮕bYHC w}w:V endstream endobj 142 0 obj << /Length 2410 /Filter /FlateDecode >> stream xڵYo=BK)pR f]o] l@ֶRT~ g$vA h9JGoRyt5HʊQQYz6=\'Y%dT9|d |=o47Ínyp/h mI{\wOLr3S1i >kuq&3i[޶'fQ6LbhJpgW$8xSjե;(+#5Xv-򞕕ؘYPKjӀY"J`SyKsqϢn/9e~-JCޡ~l3UKi*)`:5Q֘gtD (7[lrɼ@^bwn2UYx$oJ#MȎ[oĹ3z狤8uw}|y2DU#ɔʘ%Mfu"Li8@NS0ĄFRF(9{0W|\f~&yYѻ3/8: Cgz1I܏:ȡ7a9 8<~ /nC?T|[ɐ@Pr0͚WO.v0_%YN.)| x M~:WY^8aӔZCDIvbDo<‡Mt2ĺ0]QF,@3vAitqcJ`Wt٥uTMc1XBi(\t"ߢ| @r@vF(yt];1YMN$"CՅR?ZUU~Ț.{}.@K/t*Z(ђG ] lZqu cvB'x[4-YYyܚyY;i:5'oz@P?%ֺ ϲ U*%ʚ"Țd Al,㜨OBӠPE\{8K!?*V!+b >Urg+9"75,t-\\ZWBA ].󝀭 =~DنE}Uƚ KBXGq:ɫ Ij0}8a윓r8~Y5nߧ$UUY^Rnpz.tvLPSE՟*-Hā > Y>nn9̩IR[_A1ˋ=" >dEθr ILa;vJ8{rr"vvR^TlEDެZ\,vAՓ@+v7ğ>nhWI$8t_pLF?IU% ʉ2^IE;MMPn;/y_X}_Mo==Qeՠb {{QaN76 48icv_hE9Éd 6De*K']Ⰵsm(+ /8QD xZ- }pmNs[+ +ӏuЃGӄm]ܼ=.>.SU7w3`:9JlO83Ԩ鱉:U^тםG$Ps" {Q-7VWsM}ڷ#sc}plˋ Vyagfl~:K9N$ ,<("R#?gn<=KB> [yJ=N|~-V endstream endobj 151 0 obj << /Length 2069 /Filter /FlateDecode >> stream xY[oD~_тt Y 3"I;$v Xc.kiX ).{^ʵmEdypDzApFg_շ^? PZ|a n}Ω1Hy]%d!h"'7>p\TϪ#'{DP-q^e_<{`nfb8v^*bj&( DC $nwb@.ĚrgE}pŮ.jjlx6>͍~a.nQy|g}bD!fO-ޡV[ZN\im\m' &-m.Uy.22%XV+(NjD# (%P&d =M"tU/>C^dATUYtv$[3aeUY飸:$Axb >g[^w#$d$S sS*[l$ArLc^dv{^|QN|*^ ۶K$OFqKeٜp='#?@.GTBc ]pњJ딭ʿ)"%#̝pʮPg`xc%W pHщ*u3 DpS3mzQr wCU肴k#!T5r,X 8^JSuKB,ɍ+}:эЅE2b4b؆n ®$F|JS7(B8 ͆X#Mb s&42|d]tY&vaGlבF|(hw߀'pPg{RIRϢʈ 9$">4Ic_%q\@ K]qEe(>Ε?B݇a'<+#Ҍ≂)9^(c&=:WUyV&xAӢYl2n3MgsޫnJMJ{(Nɶ2毴. L[}l o񁧺Y)A6qRۏ&,Ó1Px(<-1`\Fa{2{,"`acHܰPc#11RՐz|w%3cnrsÍr$Pdag?`MHXx#) lLJ1?~{6%xh>(Rb*DJ(Z!DnCQL.qQ^.\U^G=9uǨ@ {fwrۻ4^<:WGڐth܋}MDyHStqw+?P.)äD͈v " L #\㨙^T!U]zA(UwRWx%袆N绠5S.bXa]x+7@Cf<5>Pm.w=4l plS+s)Weⰲg׬ X;6'oj'Լ7=!K0UNj6QkE㶡(>"ߎ~?|c!@=c "qOxF;)#?݇Q<W#b] Mb0Z݇ :xTA%q5;c(3J7PAs ~:֬) DLUڌ|uE) endstream endobj 156 0 obj << /Length 305 /Filter /FlateDecode >> stream xڵMO0 >|5`nH!Z&nuq'VR ;pL> >> stream x{tSU'IrWi>A`x(q]`Eq5uךYu׌:5 ]#2ع̽ҋ"A-GZZRnҴ3G6)C9|>)CDD-䝃yD vK222)6QRr!-s 6!n+gymMRgt#pAt:O%&&Jf#"0ӂ 0 $%DͦS9 #ܔ!b&)gႷ9~(#2h+/>Uhi|wITaiFל*\vbx}tŽ ʙעEY WkJ$fMo R3䤋'{{F)?w#IMMnEY좬"F(+>+%~z٪:m[M;1yYSBt8t8Uj7ԫZAZSͤc\&K&f2~+iJ](>afΜYdTb՚u rx=rPbPi!pc^|zֽml S9#Jiqxh=>j1Ig,z=/5Dtg˗. 3I%eW, Z":{qZtCl4~d4ڝc&߭U34| g9FYOUW:qѾqv+m<ϛXRLL]"Β3$[W^hkxM#@$iZwdL~c.%$rE "1"α@,Ȉ#2/;-*"VEIr:"R8hTn L("sa^Ӓ:]]ך-Aj9AecFU0pmΏOd(c~GN$ɦ>QqA68ڼ5K/߮R<ρbIqzFΏ֬jjV|0LqgaK5{z:Kt8:h.VɨTku qovujVM==q2Rnظ(+ʌI-M-M#"9N{OUaHR$Ɛ;|Q2̌8,dLF)Zé//Gx2^W[_$#",6^%fdT_cMHo$ܤp!JJ1{ =ϲ6 P)7=ԛy/"ڽnCo敞/'+w 2久n|2{򳧎z}~F1e7BVaŤm cA7&%^oԲ ]Rr(ڡZS%CJ?|`eK'ǜ{/_ Qfmp+uu3g>u~uo+ǎu]lZ}l9V0+5&-MiӉ#n؟0(ƪnپv/rednڲ]RqnEƹhm$"V7pZ&V1 qD4=%5DTQQ󂳫R].^&W bួufKyUEXÛ7&#nohLHKN&l52*%5g>8 ͜trQ|\l[UѻNiTDTe1ϏcL+dِn2aa,nV/tw nV%ˎ}n#Vx:VQVSQin ;)ɉ}0竬%OOIqwY̲竲`12H{z:NKDW**cre7H9-?W37+w^V_B\l$ ]].:)InwQ}>_mmy^a\9?/`[w#{v7v{1Ҿ?K8sCQ,YVqӢ/Yuj5˲_\[KSeEy&)gzZ,:#oW酢ٛ`UM[wQɹ7|ow*jx kX=sEL $9ڛNe~Ţә.6gwɲtq(FD% #DzGK[kn "!L ƴëο\'qQVrkb&=~ E`"ꑃ㩪IM2={!bcY-l(KJp31jZ?8WskGqJej\wk]|||WWW5ie h[#a6[U4mK[bfjAuz͆_t`gf&E%%{=%>>3T K*RS-~?.'FE% 0RNYKJ4Z( 4vM? N7-"Y9Y9xFv*C6b ε6+jfO 6W /gMolku)3­9eO]UZ[EBRJ`Oo{N(̖=bV˅Y"g:KDZN<#&.rDV}^\[]Ҕ\iʤMY*0ߩx &Qjjjn/DQ"iNO_-݄13nn nsAo/->8p'P DED3"2ODҘLd0P5s:#0Y#` @8 p@8@8 p@8p @8p @8 p@8 p@8p p@8p @8 p@8 p@8 p9dYuS.^9C =ztѢEr^^^vvby׃y饗6l0tvg͚vJ-ZTTT4v,ߗ.]:m44W8p +++*//q#T ?~lٲh4X"h~_ܷo_fffii֭[u:#<2ի{n@D8xmۈn0pΝ/rff&˲9s}b1Muh~ /++Wh4{}BE޽^3gZݹs端:Zll̙3ݻw׮]{uŊ 0p׮]gaO3 M!7n8$ҥK/_* ,:\`K\zÇ> 衇O8AD}ʕ+4lC:>nwc׬Ysq۽gϞG޶mr.\8RE .rjj_|1tXPP0k֬5cccg̘gϞpʕeee{>%8 w7n>z:Sc=6Ty_~yٲe z'bbb~ [?gy"$tD~~  /> >> stream x}p{gg-7$eV(Aڭ}*j:׫-VWd3{읢p("Y$ y yu^1&3! Y18MCO7=a I'"e_wHIɥ@s̝Oq8(pG5J"J;*2*u\/Z~OڒNDZ~*O 0_Q"JJJ:0 7%0D$͙Bos|NI</Gg Zk^ & 0ԞM7F~YUV?ີkAgKM5İ.\nd}-N\xnMI5ŧ}Q0p>-k[oNMI\xrw:r y<;6mQv2Dz (;!T"Z(;!;5qnWuw!&畘YS|ڈ#-Y#Z fsz#KW +/\Qt)RymnHqPCcjuzAcYttj: J"lWi4kܮ5ޕC 3=])p| r̺'gBU֬c}^ÇR=ܘO>#O6ve.;;>"mklnOYMsEֈ(Ntj":qKXLkֈ(Iz ?_8-&!F6hv/3Y/]j`goT|bcl:+3gOh߸uRe6v_.)&&Wz :|`@K 6-R[{mQ- xhzjлnf4~{G̴?1! ]nT*/^Z]p'+(U͚m#"B93fdT kIi)ԤX{_ 3#,ྙ`p˖H vt:Fio0H'",5ި%f12 hh%nRpa1:c!^(rpXbOj"6n9f~Ţ{6n*a-^6[g/X~QϯT}=1ChZ;pW1Ә^ q7ۺ5CDWU5 TMp'T&se7g,]l  bBY;:_|镺3Ӟܺyo_(Ťe]\4KEUsMNf6JZaoJDmfII֖DTzrQ㿛0&ܴ1SDǚ)nپv\,t836mٮP*طзEyHDF9JE~m\ td[ЩJĮ^"JMIr9VEDWQ$v=={_vfkyUE"o68;;LOD11eZg8~ ^٢S2z郣7]nz.FID>IwSVQF*&U*3Y_aј1 1mڪDWS/6mUp6*ce5x^.p~ߗ}>ߟ现}>_e]%/q~zjrj}>_FD(1ሎO̝>+4u_׭5Dt2.!);o^v|!b:^CD/&dΛ7Ddtwu}>_b|\eŞW]]]Sn |: B̙3Ii^@m^7BnSǔ*~ي_v }W Nͷwj4Y*hxQdSsk^KKM5zG(:}`ï_auz eI %^HVFdl2@'"Fmڬ( kxbVSnY6Dj6VVZm6.6FfcӐ#B>Y?zdy7w\,̙>3b=^Ӿ~,uhh]r_gT*8utu,;%ǩZںf˗+ %NmDTrSuP(Jq \.57rLtO~ Ͳ]*9b/0̕kVŲ{sZeZAq!wgcsTYQiNiap׼a|O?4ƾ]2sfoںS*7mAD% 񿎾SV皡s5g΢iс%)i޾.~3Y.Їl]^"eCM^QdY'JJ/A%eF?yï8[ q#=3-*9<|f,=qNtuVKقs<2ݮ>";g/R.,^;'_ju V.f\? sT+~VWr?w*TtOvޣO܇8O5k7EWSQf=*1=khu:5U=,x-#SU]Q7⨌>H S;axꚺĸ 7[- "ӯUTTB l"b+==)ze6Ɂd^ w Cޜ yɛ;ɛĄvܵ+2-9%V?aSr[~{LNI 7mbg~gs[gςV(iYsݭu ===7.$ZiniY%DI1 ՚\YUͩT(iuѻ7F~ÐV/;ynfrtrRgSr샏?3tRQaL>-:&.>I4*UgWlJJdQlj0da``PEN;_uν4Vxhݦ9Åv㺽'*z2W:f市 Օ7jSg["l@J;StQrn{;QkHLN 6F<終Naֈ>@`X:GD^2#6>DR^\[]Ҕ2h(چOOSf̲DDTT6Rn-2s{+e4ZdbD XX#QdI9>Kbl>7M^*X` 1v#p7jcCxR]>{)36?K)6RaI(I2Li8M VG_[&R`T6Tͅ|IBއ9 ,|D4#1, 8pGe  @p 8@p@p 8@p@p 8@p@p 8@p 8 8@p 8 8@p 8 8@p 8M,OhyuƳ]|.Sg 8=hѢr~~~NNj}CK/mذ!vϚ5v,Zh쁲,]tiL&ӈف/'NhʕrxYY?|>b{{f͚'N={~m۶mϞ=Nl…P(p}uҥqvÂYf\3..nƌ{)++ #\reYY޽{O.==`VƯgyp``ԩS֭ _ رcG7oV*DT*7oϯZ=ӿկ[*ŋ=>/'''?Iׯ_O:g/QTcl޼_^l |'bccӟ?, p'=WI= 8 8@p 8@p 8@p 8@p 8@p@p 8@p@p 8@p@p 8@p8 8@p 8@p 8@p@p0(ǟXUW"zxs0[( endstream endobj 146 0 obj << /Type /XObject /Subtype /Image /Width 208 /Height 236 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 6240 /Filter/FlateDecode /DecodeParms<> >> stream x{TSWsr<> "jEQrgZC83JckkR鴳ƹCZW-:v]:;耣B GKxG^ؘB@@~ug>{6?ArXPnے)SQDsDؙQ _4VWP[bA(bexغ:lI͛oC.5<<~TVV+|pvKk(DWVV<ͷp$*p!vF8whOFHdD,o>4^WzB>w#Q6G0nEcyS oGO\ne}8:zջ|0u)h;0*!G:ZD\bZC}͛7571;w믮F'h|8㯆)5mrhQ_ sB͞wz:jg/=0{:rGc=Ѿqe!MSY.eI//Z S~4FS|ZſT39˜q$T4B͋Q2@wJ!~s<^'wvK9"sr]@Us#J_$;t}G聢}eF9O_x+$IQT4'Uw5YuMrW|ɩqaҽG y WxaPɃl~ 6) "q_=le,"A;]ZѿjBLTgx~ 5\{rɕR4 &IN-Ta ΍֌m"H,ݟbw88E?yfy7/(zsMn_dh1OuAW{NMMB̓(c0iAjӄA@l3&O462vCkdJbFH]l&p[MDBii üQUaKY\Rݬ!O xaޤU|eX۸_&`XXi("{L{ǫ$Uo-q&; l<KousHGWл4_Bxٟszf0`R3N.m6ۺl8LO?9l8uP5q\OWnU@hP@WkCOgӍftFFغ:cŦΣ/66̜e꘨:΋e7Y|1͗|;+y4y|_f p9lŇ?pci/>aW#`L/m,s~2ܧ^i8)q\6pcg$O^Q$ L$ˮW[z| x9"9G(gw;8l.XHc\H\͓25h.O6;-vs_! Q #ԲKLr=j| *nv< fN;{y=EV4;d,=3gaΠ9ҳlcк}:E' 霗l3~4dt]*-@&ͥRWp%*T %ͣRI^u&dPlRNa xG0:$).~}w؟&[5@dZ'e?_B W\AIeK< fK<1d\<):+ hXL5ug'2`ˊщ#)%\.QL|>sJuVM׌[W^K6&Qd2].WeQNO/> K/b$ ]g<1[ !yչ7)߽p9r wXaћ ?U|?c(`rL6 C5%\篰ʛI 4 ,h`c q??2YplRjX"겁}v J2f%>&IQ`2{'NcYѥczqX h\obk,2;hʢֲ?9QGlUЕl!mvb W*D3i VpR f_X{t>)9?$7Mdi7ws%e{rD n4ɤ *ZڔJM/-URC$!)I|C$/2Vm蔤˧:hc+G2I%Gw)c6'ڌ]~} "MXPggc2F+5\,/|Wb”$͗>0ΓDX25{mgK6:- W/8GM Q\PUc}O* HI`Wp$b4J)瞼>F=2[/)A``[ w#ACP8AACP8AAP8CP8AAP8CAAP8CAAP8CACP8CACP8AACƴp:NFGG+hVɐpdeeiTN٩RSSZmVV(D"V%>С|mp\.nܸ񒓓oܸ\.733377wķ<~ܹsJell}ϼ{S*{bA RSSݯWXqiz+VSSS FvSNofMM;}lrر28p`˖-۷o裏b5ᚚrK%>С|mp\.g.|syN-KTTb̝;zSNU({~J~gST~~~}n'ŹK޽o,WPP:HԂiiif}駟|Zزekkk?89997njnnќ;wKmݺo,$)#˛k4'N۶mێ;\.?~|A7o/=ӧNX,;vXr%\rǎz~Μ9C zꜜ곀jYzϫ&Mڱc^?>,X@%''{REEEQQQktttQQw)쿱 FIIIIOOL=F3PĴ 6,[((jٲe7n\p'ϪUxbV\\K/ݳʺu.^)7׫jFg4{{{Fc^^FQׯ$O?MҥK=)˖-p8+%KY_TTZvڵ/g]~_X" @վk;1mt{),,4Lr|˗/OHHVCFkeapXf ] endstream endobj 147 0 obj << /Type /XObject /Subtype /Image /Width 208 /Height 236 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 4925 /Filter/FlateDecode /DecodeParms<> >> stream xypIe 1 lH4 ,6ٝtٙv&١&3;l $4;%!B(6` >dcc:|ȇCؒi?/x[y* W-`N|xL^ ?|wFX 7_].qgN+\m"jiQoSoKKr:ʉIMz":|]g*U.:$ DtTywWǢTFL"b^cuoYIl3_eXw!wߖm۵/ awMU%أE?Kڋ{ayN\ZoRUhqvwӢp>o/YG}6GU6хz#Adb=DCRJDdMx{ s6vɊjD5N"`k[g(ug1*h0y}͗;ۺfI2c'37,)jtJfӊjey͊p8GDIQT™ረhuqjZ ]Oa>WSU?~S۵Zm _SU"o5Z*tn?_F c_ȷL9#VZT٪ʃ>imK-ihyήa(Ol8%5IDZ&wifwWgw$A0ܑ4y"j5N_4-Iib۬jQۏ}Qc7Rg~_ȈȒY "*w\npi0;[\)Yꬃ.h2\]|]mMԧj^>SA{ӖU#hKNm1fzXYԱPXΔIsB3:{-vWб4fֶ+^ψzAeEg0Ll䥦jxؿ?Lsk[63-{Mh3~RKKҥ9OoU4+OW:]^󦔤E+Nwfھ,'zlV=ݝyQuMMǕq 0׺5 )z3k5OnKT45r󋶖nh53l["< "`2 Np]8ܾ!"Z9&=5&쬌AO4ꈨE(IM3^7h9jZ(uwkmYK&БG+&"=y™bx>8 -]yk (-5exhd;~ȡQ%W,E10,Oh'Gc̢483Ҧ4uݬUgs Vror VV)S; 0/yRN1n݆AXz׺O#NG۰0Y򼮻Y_jΝ7$M>a%s_-yLg!Fh~-P(L!E23'Kf'z|VUc m:"]jyck^;_{Q0{=ug!]o(jy>wٜvwzًھe)?9oQ?0Z(VܺmnݶN NR朡3=cUIȒ|88wgɜnyHUȇn$q74BDq;UUטEQdc__kSC\>`PHqp9EQ&b#/o9ƦfQySĈXKG_"G>YԒ2•#qQG<źßM^V" G.\ji $f%K_fU#I&kF8u)(Z=+(ZcNbF;]qy-3+g2^˗{{_fVN6vzhrV ^nyljepz/iwNd~Vt$M7 ӿ#'f&ffU5>ˡ< fI>V^mkΈs}>31)%5CRHӹ=^U YEIYն1Q&ܾ`mY_"84Z.˗\@ku:5Р~dddllx!of{OmnҜd= Z\Ol{]uّic)K(*ֿU־{^1GGG#+ ݑvwzFFDdYKS3 @D:g͍=ݝYK,VFin؉fW֒exNwl-v/5*9㓜I])29#^$Er$߼gj"Tp Tkyy9d FGWOeU7Hjd%R1Z%,*#&jrjQQw&-Ѯ^`_`FN`|9x RL~gz- 8@p 8@p 8@p 8@p 8@p@p 8@p@p 8@p@p 8@p 8@p 8@p 8@psZu٬ ;p@III\\\nn޽{g^pk8;wܹs6O^>|gٵk}W__SOY,x o/ꫯUWWo۶h4>c8{7n|mZ߾ /҆ z+^y_ױڽ{ /j*NWTT_Q0vURR2d׮]yn ggΜٲe7*bv|…≇ϟQt={<EEE{t|>^QQlǎ8x8-uڵկP(TPP$ʛ7o~ڒ~ӟ]aɧיriiiii)v?&i@p 8@p@p 8@p@p 8@p@p 8@p 8 8@p 8v 8@p@p 8@p|boUy<pp[:$%9 nDĈ'J;&x{_2 endstream endobj 161 0 obj << /Length 1493 /Filter /FlateDecode >> stream xYKoFW9hpE.EmChH+R;;}R6@/;;;;͋NGQ:*ի2)̴櫑JgIVR'i_&)g"Z5=<-i~㔎:x3s=/Z̗oֳx%EF}Hf8zE^xߥ:<򖟆vby%/6QI;'ɣX%޽gͯ=wOqbW4xFQG^.DZD6޵S͚tED\RW̹nYI<'3QJ̭-QoGG,¼0Z5^ ,\UZ +iX9nR\bf\R`U8XqݶQt~r\ťxSdcc a?RаyvUKa>d sKky&a/x݉lP9x4y}Mga:0Ajm1SK_e9%Q+i(#6rw.͎,.djk+;Ipչ<}f 3 ݂UUKmzjGk/q8x~.әO|,+SۃW\TA;ZJ)`=hWZE,D.w*ˇ_^mDɰX0'04˹7 ÈJIl?a=5 Ǫy Fbu=!BPfQ d-6x/C(^C176 r ȑ :؞Ah%Ҳ #*) ;Kʲ$i@f~/ endstream endobj 168 0 obj << /Length 1680 /Filter /FlateDecode >> stream x]o6=Bl,bERǰv)Aq$lS/R C:GfU%?dɣgU\ټ0*2SY'ɛTk^uugfnlKY#Y+<3z[at2 L=ɯa|",lv0CB۹JofŖpgx% qSEާ-Sz?'0~Rc&G8VǤf~CnSjmsSuY[%Nt4҄Uv~J2ɶTZ$maIjN9kIUQ-BʹRV5 KOm30M]9]C"s0Sj-R󴀜8pBvI# s Dyr fD7<J8'HWA\ \-Pr2z]R~AT#$ǚ"LY|e\ru>{]f]Apc$)}( : Hw4>V%DA~{'O*btHˤMsÒ)JWc@dࡔƗ7D "7={Q rp!gL?x/˜qK tO%#lW (KPeX;Cx% mot0d~+%]4s2'Pl$né:}a(f\ޫ.C1+ꡱg@ͪPaQ#SVIYy׌(: Yk=C8 rQ5ߕfX[0.}z`5- n0)nE~`Laȟa#4B4E8UnK 8LPI듏'3}$Ғvj]f8%?mO~?sI=y05R֘DW) OKnjv|ȸ@ol&dfph 2+} K.*E߼˒KXisM(֡%؂%V.34rVJWzؑ$5t-~R0Ez*H?EZ'W^ي3=Sl;fG:r8ki(** @yo\2i9q}Z̛Z.(rt=h`%ˠ\; U!! SdQNDܔvPV5Nƿd( endstream endobj 165 0 obj << /Type /XObject /Subtype /Image /Width 206 /Height 227 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 5613 /Filter/FlateDecode /DecodeParms<> >> stream x{tTս13$;!E D4ĆעBAj %KyKBSkWkzYVoVnʣd<Ϲy%4YYY;g=|f}>լZs;*K}${h#! x=65m"͒mٝEih0H;*K@{zhHv;M&iEacd"xLj}j́8'O|ȱ .WTb&{0/;[~iqYYY<ZK;,D Aol6.-'oYۺ7<*kv\G"?1XoĒPrw^Y>k>\Is2&dHD4u *R̿} Ft)9NFDnlu*Fڷ'S_Ԝi'[<Y9 ô'圮i_ь{G+yD4}e45zԵT`n?: 3o@" ck S#xDUИe0V<9rEJ/.(d0 BTRHApX p벢HDq R@[6[aNo7ؤ<)'3C-ePQJr 0;C&fCB2 #nwwuY#n" SKf)ߵٹ1}`ٯBFE+s::(-=#Y#(d~E@. g,Oy/;ze].7NJT7c[\_wwwH r9r =)iqu绲D`jۖ{YٻrA ?,=N"}أwl~fsEI; c\ Zq1RbՆ>>K-47)U[-N28i4j"!N}it#&N&"e{ ~Ix:c]~:raswa1M6oijuTwuDQ\prg4--PU{]HG~ܬش;;&N:/X#RJ[Y_ĕKntöѦ>CeSF\>?T;05X{̡2!o SNGЂ~ SgI^OD˞}˞/͉lF{GQx"ַH Vi DbV>@"ŋ{׳DTQ' Uks\]sr]lUM^iCڻpV |[u8qBrRNH0~iØ9}&)X/i$h2"Cگ< ZЯaꜝX}%.(^XV,Vˊ>_1z)@4Lg(Q9-5Śk8:bDJ$b}'g_}y^{y< .]CRr~إk 1QQ[\^g%9S{r2Ԗ,^:_f1sx>gSZB|qM)2۷ t HhИO>sYunP g#HfKG(Ծ2zٚzZ֞&~pSB nWC劸8%z|MdTQc0>w(p%t?b2G+$$(䎴46@D{~^DPGDszh"{[+SRW|Oa;쵭ɓHEA&bt377WJuuzk 55gt]n`{/)R)99ծ ,}򉆆][er>Ϭ[ե**~:0ihٲޟM]g'}\ѷ=Xe/_|P "j׮ݻvȬ?vTZa0_zyʔ{[LgK/U k\.wGDEƽwrywu;ւ"RT{%~WUk4RS>>ZmF972III+ЁX "yԯj5R'];^ v nC @5j`_`D?-jDyEf* ej\yP]C#p7jg͚5)))JrܹV5TN^^^VjEvgŋYmmm%0yy)1;vmݺĉ'OP(Wsݺuϟkjjzeee&{*{ѡCf̘OQg͚G)NDUϟΝ};`ho\RW92?἗---~;DSa/ԩSl#G;6of遻koo˓ނ>755n#*gjjjccnhhHMM=r_EEEhݣFO1U[dIyyy}}>{ܹsC3gΊ+t:]ggҥK̙rDTZZZYYYVV̝;wٲe87jSL)))Q*͛9sf[lIMM1bDaaaff͛f0JJJh&ɫZq䜜ѣGO6 :Yx]OD;y?;@0-8;fޜW0Q.O@505CӀAW `(T{ХTP ܸġi  a0uՂp&buu#ryvvvUUUA͕d[n \uQa':::::9zhP,… cbbC0ܹsʕSN5ϯ_d۶mk׮}衇L&̙3׭[WUU嗧8==|NtOx<555钅}ZpaOOO6lxץ+Vou0EQD[00M_Vّŋӧ;G=}4-^P[ZZވwY<vv'ʠI)//a"jnnJ*"-'NII\ ѱcWRR2}}?~RBiڠuhoosa3.NYYYDt%~Op Dz$BGG1m4J/R /T*~ DRPzPCh4Z,/cI򲲲B1yI&)3gΔk ȼy󈨺nK2V W^=z\.WT3f8p@\zuFFqYYY6mȞ={M{ٳǛ!Lն ,5Hn=P0|bu;)jDF5̤j&P @5jTP sp^ @5TP @5j@5TTP @5j@5TTP @5j@5TTP @59n5-h^ @5jTP @5jAY79W0m]5&  endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 791 /Length 1927 /Filter /FlateDecode >> stream xXKSIWѾTw&fmr8vvH݊V ~lXH1@_Vf,M&S0$q#q$=I@2ZRJx_A!kmX6~LH{(%q$(9,YPGE,0 jrYC΁̓6WNʁS㥣#"X,!صPĚy-PcARvpGPb"B"(Q&R+ m;*L@Ĵ[t%K^ƒpܱ@pFN 2qIP[BykY+R`$7eiZLJyI"*t6#C9B#9O)290-/tN 0sY؅d$Vđ7~ŪME"FJ Ȇb08`W͊jlOIS xՈFM=TXvB˲٤4Wou.zi3mR|bFT-vIy.ˊ3)׋vb|Y7՛"W鲩 rQ &,8Vo7XmI tOʍ.ٻ=gGG,Q {NgA)E3Lu~M(77x4рͭ;*vm՞6TvM݌Rɒه4{ts>lrA4>衘Sìނ⢅엲Ύ:qs)^1גFv #fdrVv.:FfA) N;σB',t#Wh~>6sBwo4ϼdʡ_“KDj/AmDV>Wm;!˖˥@y)HE6`a^FY[ ۊSuhvfDg:,+406RMbrT/ &yvSb?'8s7Z_}i`pڇV!}Z~#a|&`_TaqË;k|Y C-,ڴ00<h<Jm˃LvxhpyH'WAKy8v.P/(^4oDrwH5Fl> stream xڝ˒۸P|YMՈ!  (8|sp(i֒Of'JA6~wCb߽Ow~E5֖ț̸maX#~ݬϏ0~N5 l d`v7_~)ep abrSO@ / n*8G;OjvgeU"=U ?syUp@-`q>kbmnF`eXbc.TyUd.t\.Z^ _];=C'~PG@G͖w{b~'Q@E^frsm}n@sZNtäe ^D x !LAx=zV|' `.rzx0_m=:`8%v \@=G5p?TaQfK#=>IEMG"[g'hؤ'Q~:qšxR_4HP ~o۔5uffou35}{SP^Xk>㉫Nx̣ jTz`+ԗ4"ΪV6' {҅2eA0gy jҡ"+qز”=jïZ%=ո 1D  S G;9z`-X>NzZH2~ :b!klQ5JPj(F&3Se}/@,NㅇL\NxNN2:mY圞 J%Mf=k9>M:Z6O_ʏ-0eiEǍPs cYoBx9 M'QZiRdImu榒AO|dq~ (yV67nE4 إ=ĬJl/m}iSg)/(ZLL`3byTmO|kA`װ&|m:Y{@uuN1d-E6$0O5?˺] 7W&Zhd4ydET gJRCG'YSz{U í擟 &檒n8ȕWvxfac4n&N;WN#S'/S'p3l#j8L5BWyl}׊rcL8yb:O/Xfr^ȼ4yFa>& q%a&;Ln%b@gSIi`'_oYe~(ѿ;Ls *n<+{6Ry4_Y  ,}=1(Zyhx09]eV '5[:5dꛬ薶*?qMV7>qQJD> stream xYێ6}߯0l!7`F6֗[pg{L>[Ygލy͢ka-ҥРs$@T5(rUi%銕q]+&&KGpϋ,h6ZKg^jHOv?:54|,ݰ;&46mRСR5=7myݧcB{KϞ]Bqa+\|ǺmӴXY|8:i}HHՄ:M차*qkQj6I8Tv\EgQ(O==KPښ%)|Ctn\%cH[ Ns"9n|Ē$ncQY:.ysA$ iQ6d\z0z<a!X|@ФnDH嶗0\?PAw^_к0Wdپ1 ^ʹt)Mi/ RB&A0#-y~^UԶp,^^D쉵/$tf =`Ѱn KhVa&(t q vIJ) muvȊvS}'$J}'{|:GyO$|QSEr,(9 TSSYt7 h^;;|yE ޭ? <ʉT@jKGټtRsY{۪ߵ=׹ػ{U.6fc1{4nN|O/ DmG8g,q۶8|>K!n>88NZ LVuO,w"'\1r fHvl^[) r1r)T8УִӋ; endstream endobj 187 0 obj << /Length 1677 /Filter /FlateDecode >> stream xڥXo6_aIFkHI[A8eSHQ6n]Yx'ҳ˙:Gwzff4J̻F-l}}Z:=Q$C2~m*f*/L?}ןǂA" LV3kA@=)_j3{[07\puE|ʲx~<\pp푑g#k.翯~:gVxUU)˰늟upc4(_) oDn?0We"W6w8ѮQx ls$c"iu ȠW#`+1]@஘[гcX_V*} v  |O濧3s oC+_8Tcr0EN/]b-K>ZE퍸CojooQUޏ<~]M®7WnL rfs!>@42G6r3mbq`B? X#wSCfD8 zfM Jl HVT *G/I6twY8p/$% t{l BD=Pn_W}X9I iHm=UEq)ś#u,,MwW#O xHEv.Bʍ<$ qsM~4_.z}J׉=n"% >=laU %nXe-|@Z'u0[!:^Z ?122 kC4.C9>!]k+ HRԂByk?yԡ~2l2˹PF"25&I >Cw)#eQ*ۻn`?Qv@Y̓nVz~%+KwaǾDr-(oaecf,ڋ}zXj" 9kqxkƷI\JoQx;3bh#C&u>PHf;t$:jcS7;R 6OlNP{4P3̯YG[؀YhR^Bmn-׋$.ѣ;mFn_Y) C!dZbzx ?P4vhiϲ2m ks,eVx -N|QlqzYH۫esEiGIGvM|;KF4 f+ks#p%}= k[ș:TdC]w\A¸@f?馰6k9+ppmuꩫGN5YV2,dzDsIdRc }#ߩރ,Ikkr)=_ʁ`&)0IƻyKZ2gHߜj"u!ELL9{V8ڳHT?LBEݗx3V,*ײ:=+T9cRO;1n6 F5:~ fOB+k@|"8MϫMgwPF^K3ބ4y91pC'Q_W/竬]CK3.3۩4^{SȳNQQysum{my;nnlcq1ػ1TE g~N%pf 7bCgٔ?-H endstream endobj 179 0 obj << /Type /XObject /Subtype /Image /Width 217 /Height 236 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 9955 /Filter/FlateDecode /DecodeParms<> >> stream xyxTKf&=!-HB" YHK[|]RAQJR+X +P!E^Uv/Lf_DžqLf& <<3g=s.Bٿ|UbûkB"iCWÇ):bI7 \-sugI1c^hjyE` KZ^bRHmm-BH⻈aH0DϯhtC4C !l%ٵuy  *Sfkkn8^KdA0 Ævi b/};6䮻͎V[ZFMiC~-4p˴l&1 {/6[hM{\Ćri bmTjtq޿ # ܽ|6R9~ѥFi@JѳZQ4%/tv8 S51l.;-% B!j`4$]D!^Z li[,tO~O4ڷ[?btkBĨ^H`6FY)KeYZ?۷f[? E1l0j]׻cGٗh Ǖ 3 b%QLTZl㗛[jkkq8]"N#Spټ79NgMY-)124 $sQSL?b6֦]_}ȜL;B$1Vixta2Jv!ϙaÕE#s3SAń[䍱 !Ņmִ,a:5m5RS 8#jO[{ECG0, E:~4&JIb׭6g[s`{!$:^{Mۄ}6L2x$ʧ^B>MzfN16{zt&)mfI Boa_ʰ:J]8.1b)3n2U<{< njם1X{m1qEg+eGIg$ϘZ6OZZZ~4c#s>ظU3dd7ٴZ dY>v]U.w\K8Mۛ4$}`ZugO}ޢ`AIvqQ !DiEE0M&Ɍ'Xݷ&+;/ŚMͽ1#WwtW\n~3 3nEiԎ֖yp,/Dn)%s y#fί_[OSM32"FZlS3QzzZG[szfEtjfXL:vڳcwU Æ.bҰߢd!AQs?X{s?HPTuK7;uĚ{"q]ҳrr#ah^G4:xpVv^qD͎r9!{]J'-*i!IJL(`X6_?)w8qj¢%Ǖ 4\Wu<&#F &f N-&|ȡꢒ |">:|`ے|L]Pĸ&ed*)ǺbMQ,Go::R1UiheiR͐6v 6SL{lKi,+B={UjRwvGJ_0 X^Dgi/vmܼpԤ7XRfQƖNX2S?ߴd?Ǖ:Q$;wtܢΧ'a-m7{xq&5- -mis+ӓT~3oĨHFrahJQkkjz՛q99鯮yd?qI "{O;2( /_?lxwxD ,.vwu]._Y]=A':|>_cSm1 /òze:1fTAvVVy>S[w_M7z6YFjnr=3+'7_o4&zH 0ėa)YWsW՛nU0l w91_Ɨ^7"N&^pٜJx8ju|p8DgOO_KCVn~G{˧  `0V ,ۚC*QٹLU\aÿ]rfgJ"pW5jbyNgW`N\y)-b(iY|FYR[-v; |N7 00dC BHRLf4XzR,.H }n7Ohfq `/bC]ЕaYeVkzϞ=cǎU^ݻ>`FyՎ7nݷv[(..>t7<]=zW_}5}h5 /A.ɲ|Gᅤ~6w,,1k9-ǖgoʷe3sM,NjL_Kk۩gNw-]OaFD0ċ$˒$K}dIF a81(UY 5 ˲4 ð0vb/BHp qb!c8q^$ CU?x! I"$*ސ >Z`(bN >0$HPpW`ȹtdԇ Z(Fz*YI$qx)F$˲,0>97MQz^8Aw0 Z L G.&&""Zɾ~pqQ  aHeYB*Ix>"nȒGͅ4E*"yhJÑp$ O< ngU^cF ./|,˦R&c$x8i$p|%Az5*h`XVDG,cX :m8vw0I%6ʲ,P x#AyVmX!IȲdԨ> xe1SeI#\ 85*Z:OacMt:`2#1w$E "$ " yeIDp့~Qj1 ͩCv .1$˲Ve1;:CHf.*$Q$~Q$lwu4i7,wX^baY>x>4$i0rEI|@%I&UA.JHߪ}!#dY%)8;C'f!#ݞa0j~:#paJX,|[[ё3YpJ%x8"D$%},)mBl8YRHdZzVUT4MG]. ZfQ/;eQ`5D12a!YF,{UDQ>sp8]mGE.;3-;+3lt`i.*Oqt juچ溆涖fɢ֛b5$b8. J$QH$ |q|n!kaYiivŒb24A+E\L8fl6$04>I9V#ˈ^"\-(B$ąP@ UV󰜬 d04VN\`.bưl[[{r|]!DHDۛE2!$bfԚɒbZ- ];3 37CÕ& zCpD2.8! "1($II^glb4Zm_V,WY5bTG j54MttP0(}0DI$IRVFD)*J闕- "cK4Mjq %$I*:40"k]ÔAE1 h" eE)}W hVT1vCDa \р<`DJ{Ku1Jn!.Fؠ!pY\ Dph\p\EpE\p\EpE\pE\p\EpE\p\EpE\pE`A~vh4ar _>rCb[l*|evhƋ." %/?wz\LB! sAG裯(F!¡P1~0&)n:}\q}f{w322222ׯ_ 9mڴ˗_UXS6G&w%ױrܹÇZ#G{o~E8w!$Kro7̚5GcQBcTV':'wpTTT<`0q?)S+͛Mfۋ֭[>yԢkׂO_oou({{H?x`YYYoD۷;|ꩧ.\8v\oۈl]͸+rUI.2馛9mڴݻwKF?ZrK/XSS~K.mhh裏v>O>dccڵk_y?E{t;nU1 `'8Q4e22JǾÞ#6l6.l6{<ۣG]`FٴiSKKr8-a؀KfW N\L(bkSxɦ}X}mGn_zP( _z |womQחnp˗^4U{}gQ~Q̸q :~_op3M ͇j&:wwx㍳fھ}{0 ۷o5kɓ{,(̜9sW~[8FsN>G?֭[^/q555>>*,,\b[ly衇Sŋڵ+-ZHIdɒs w9g$Q2$$99qO@/Yn?qp.ZEeee=zSс9q:VkI]dɤIVZh"k6oᆏ?!oTTT5J>3ѱ_\dɓ'v{tʔ)˖-{jjj$I*))y>tDiƬ,9\$=-Mm>ET7o^AzރKYQ%;a1cƌ3fN6l؆ bS?{2k֬䲲k^}α~k:EJ?q24q͈+h+|j;(P*:S. Rǯ?&Y~X逈"?K/;=/ڵE\p\E!e}r-ECcBCeûk?J8 endstream endobj 191 0 obj << /Length 2043 /Filter /FlateDecode >> stream xڵYn6}W,E#VHJ*i\ }hk]q"޹Qd胼5$3gft]Rb ikGEU+JS9^,W֙Y>;>>]nJ.k1;j/Oâvbgt?~M֪҅6CME9xJ^a\kT8q}VRC4P/y94OKG:ipLR͞{PeKqA/7^QĤz̵|^iMs |XKxPAw0~ nTMh;*PaQPINɮ3X*x<+z |In%CXXC+0-{1wESk6:b]7A3 S˹KaAO"Ing:pt^cEw+ s>@ƦsN1O!:]V=N` c[( ʌN Z:@r:y:p658ܛcKst|>ʆF 0l#u"D& o7םhmvlKOŊL5OFP2o|*3dM'nta~>X_#PaNmR/-A]G}'cH@ "ѪU(~ XjR(o^mu@*';8,g*hF/4Bo\Ӡ~ת|~ ,K^>bSAG:7dXS0}G^mqb^Gqrj2(Y3l4Gu.P'IQ t,njɚ5+Nr x?:A$OKHtrK>~UVx>4I,$5g`fPeK岨|f\Q'P*?!Wg j@dz0bCvvƮĄNBl~v_hr=}F3Tdta4Lkv9̆CIC}?+(;vAFJX'")ï#>r7|OFzlv7o"zq6s#߯%>;Fæyq0)thl?Hc׭bH4D5ŨMx_7L6 endstream endobj 195 0 obj << /Length 1881 /Filter /FlateDecode >> stream xɎE"$zG*t%bT(+Lh:j%o? u)"+mr b 6 l-7֪bd$ΪKď.&YدVNMq_EhLtpO г>➔)'ܧ'5VkB8gCd4ѡq- `wQT,ϕ`cL"[?8Uő;i$1Wk0h\(Zi).]Vs|EWŃM-;Tm#- =J"Ĭ"ʹr`2rG&s|f# }9 IKDo9i˶3&%ЮOY+5̪n ^caDS*< 60 &=QcP$!>1X7>'hPʺ"A4P٘n|v>`s ̀+\T?HLa #t)suO*;PxBjr ]vDD=hrDRŕvg0w8Džx@EJw-C?e */}?.6pPyfʗ\L \ ywwV''w1~O<31s-[qmp{;3mRzJX(TZ'NhdkzP"o qiô+"{ %HxE~Qa:Mi%#C&p]2ͽrY,\ݐin,TT*BDݞm1)7(L~\|{*(DJ RܯRZu-^K撛{7'0_nz iZqqpeJ[okU]v3NO߾jrnݳ8&<~<7LRSm_+~k9JZ\"A: n{fm=e69\x{dN:{hԨK?|l ,R|jNY[k# LnE_;`T"އ7!ٚ, uL&VèDLIљGfmD;G73-e`}-./69&<8_Dup3oտy Tt1t>ai%0p|"6H{g'C;Un)+ʰM ٍ:K_~d73\7O(zL_ ]':~0Q\E > stream xڥZ[~rxAn1HqڕWUQf[\ËVN%9edp>2⹣~ hY ~Wtef40Ig|ҷmZt~4y\ 4Jӌ5w(u㤺B>x ѪJl8>A_ɞ W$X5{]ƁbYD)]Zb3)%5|P%_5. }+--('.X96!ydNb+}_¤%nWbp2B4މx`&?듺HH |C~›;Kp|vYރ؆9* ]n.W2 _qE:o7===ƿ@[w/s*l'E_}jz=$B5 rw)x\WJĸՁѯH%wmFFީs{nې%u}KUn_oY%ENx v긪T¿W*!z̾=C8@,>rqsH(a _ln93 m9L!RVrU[@y>_EKr*IROho} sQ=mE"Iރڵ C|zB$QrxЄ WL Md ?} 1%qiIxe/U EDs.zv+:ґ5mmeI״`tzbrvTމݐnϤ)EOIV֊zt*PAqˋPՎĝ<]'#U{嬏,x9xz81eT` FTSss}W'dVq4M /vI&mQ{tnLڮӶMO+%JY&Mp:D9+~ kVZ9s !PˌgQIᕱm<3o◽[Boԟ[:`x۰DΏH9XugKx6$dU_Rbv;jL*uq`S"Q9)#.1HJ%6$37#hZ4W&hyoһ0c&k0w-&IVYnC&r ƷH mpF65ۺ] _G(e\/OvVSiADGs`%=G ԔaBF_m}3]7r5_@Jn67>iAv€A2:RkDGfX y,PsO#jia\-=&͛A <<d|?5@dCLQzmXVz }H_$kb|F)kI*Ţ>7jܔ4 +jQ륾!۽W-^s!pּ4:0ieE'Dahn3 q iߚ}Mª~ѝIB{Ul?"^(_za\90ߎ?Zm e rl:6j"J[Ƀh9cZ }FcO\ \Z+.0Ggyӏzs) V?/dSo ORG 6KN ZnO i84)8^]}ק+|LCt!9IԊ߭?sCzh6^)To*uԶ #jMW").iW4bo endstream endobj 204 0 obj << /Length 1970 /Filter /FlateDecode >> stream xڽYKoFWʡjɶ -uC-QjTEɲ[w类ÇNdr333Ύ޼>woR^Ǫw9~8=ߏzާ0ϗ?iDRЋ@BGM΁zS, sk<^i*qm Hz ;DO]s̟m es٣ ¼>]$ʼn6;,!f,k2HH 0Xd,A>a*y̷JvVQ-"%c?SJHpD.oRҐrf&3 >"9juh1G }Gٸv13SiIcɕTiẫT{AIJ0KkٶeӦle~'e+'ky39P0:P]X?S(y2|DQYgx`gG:k`𫬠b $Um+kD9HSswQt0|ѹ5t\+V>"͞33qv0ݫ?a֬缾)`B **O\^9_D>=00풴t޹)T"ODӸ޵(L_8g_Ŵn, ?GY9ox>vjkJT(̮x 6<sLZX]Pt^'J^pht]OSzkPlǵ؎(φ0tAY3Qh,7֍?UEhȈ֥ƜzSk.8|U6iyhh⑧)NTӺZvSEѶ9^(O譼̀8$yޢ!xH&la~> stream xWݏD_a8ٻ^ @ꩽEBx(}0 %4=癙]i/|qqr&? seBdy?B*{4բԥ%3eYn_;YI'f-8Z ( )eVMxL-V,#%u~Rl^ R_gRᣡn>F唑Ľ!jLB|z}moNfW`1e '^<Skc OZ'q='_C+ù Ŗ #1Em;JĜA_W_ Iw') {BO Y[f|ڑϞ0 @%?0K*#a,aBk(t c,:'SXGL1ꁵ.eXɛlZyݙ(Q~ KKz 98OcOyAΕtA7(qLϴP"bٙ^r __):. c Ñr|AaciD+ǧ1<\h6i Y{e"E\8eɉA羇9#BBWYmtt- +3HTlum""޼Ԕ kS1W]81!diRB {H)KfJ C)3n A464*c7!FLNQ £WKDTY>DPXЎNDDs2򽀁+sLL|I`;dN̄.ެm${JPQ}mBvLj9QJ֩xuM@\5cC>HU@ |? @抏_&\Tjbnyy65aKu7Q;&lxE %arjcUy7ި?x ڳ *)/Fjܰ*G4GN]fG;9S{CᲓTe sm0[X jАRyu,j ,MvT@) TS\?xk~D 'IsEFϞ+MNjAwB; `B/7DI]La^͠^8>{a/A-hɵ߂ endstream endobj 207 0 obj << /Type /XObject /Subtype /Image /Width 607 /Height 490 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 34770 /Filter/FlateDecode /DecodeParms<> >> stream xw@ !BfA(D!`V+T=bD։vQuV-T T,hP@$ "Ŗf4x>syޛ{{Ahz~? 042=ll&N0=|+ yVMrbdj;N^LA+uEM=@WH56ETU%C6QSIqq1 q(}t`0p YqqP ڎdA3kv~n$v֫utt('Lr FPx rq`vmڎ/`<=X+W+^ꋕ55{S`䜦N@{jk k$:Icڊ0<ێ\y&D4тf~+=eҟHMRQƏuyeqq\kk̿()BZߕTΚTOI$r/.{SM0PUp#@!ՈJX\cSoR" A t::eުr>HVWVRR訬}ZOTQ^q`,^KȅOKIYU!x8 rr 7nc rrrpnavDaI7f>/混wEJms>]X[]0#KVwtt;y$a89.TcOp$q1LΝ4- qGD8`aƛ(*- L #*O7b|IQ"Ayy!" YSUEyL2EGU "+޾xJWJ7&Ru)? Ф|^KS}K)YU[D BVUb <.(0644 vQBmqKיqBN~HMNod#KVqDރKVJ\7 mǞD8LU~@^AAh N0t4U5kie[w,yJ$dtA,aIf' O}_T_I_]S{/tW~yjzmݻs wvv-Z0fnf񴌋SPDwȗ_ 0ܘn&/&)5h>r3M7335cڻw$741`g[L'ߺ}D&+)+c0}muA54 XvKp{Lo~^NlU%ϊml c[ێB5)*px<tw >M5eA8])RH~3c翿44>0&ff$M4v|>ȱSF&fc)RAYzjƢIPF%K Id99+7܌><5I<ujlF<}@tu߾zoҦLP07#()6*ԢqcҲrcC3#o45(E/X$SpY8pJ #q)5KZm Xnϊ* p=[mG>*)3nn|ZYu_jL5#T%A :8k4׉P'if΢kVrXƦ41t- O $թBPDː]GCTS]U_W+XV^>n=GDQQkLOrrDGAj]E_M|:O=}C ^WUUUTC(*"MMmB9! 9TNIh;Ӡ$yswu۔h>A s9AW i54px<U q/> pA֩ N)!XlkKskK2QUAД2[:O~Q'q@"8Mv:1Wo* jʝ<*?|EG^G!HGd9.\*̉'eK(ʪtm19>JJTd]8@g90hTLZ$@‹.|uN>r/><S D뤙TXWI[^NaE/˘YrX<K)@$Nʷor <*s^iqZa4]ye't(S';  n$U(:zDU8+{ 6xSTȑ4:ӵDZXHwf/y6vKW/]A~EaUtvDW]}a ʺ-  NpQB]Me"Ĥj tL5DOs ikkSP;+*._b˖,Z0o*߼蕿TWSYh~ՔjY4I۶%^NAQQQMְ0MyVlľ|cʹKp,VN@_ Hg]]Mz Wp |LUMX+@PWN]=c. NJYs|nìgEVw;֖=a:o@ {ϒkvK )uE9Lv'@ח<54 5F:::+ S075 ro̫U&z!_|.,&"BPV)(|~ftOw~3XC}6?u5X`g3v횕= FS9\t̻r6C1RV^t$[ sjF &IaFRm3 Hm4+A-m#q7\9JRmk;Tm[U2SN?XՄIM/LLLʸud5JD7ciT3Sn؄a0qqyKsU_OY`J 1 :zM7RӧO15;&5773֙xov_UueeO-iƦF**D~gguuMb,DFwhkPkj&^flJ#'ە'ihAZZZH6ѵutvgk?־a&'`$--mqrUԚ58E---mmmOpxQIIEMNv|WWȹ RmG̐MR䯻::-<WSS{7+;UXUEmI'~$S ehQmgzZ⢦>h`lfdbGUPRxyqL12):Xyy8^RRbf֯1ъ f(mG044q8Vcc}gg'^AAM]CMD ԓYC,P($:ISEE`(!? ʵIh;0p8ƿj{ ƏW[wmG Gk;ZI-r'ڎ@mG0ܑH[~>سgOmm-Dh۶mv}YcRR:[WW7:wYttYQ{ `K_,Н 8 7:{F^Y%COO/%%E@Wd@jz@۱{^=o߾ضmԩS8 {/h` "@۱ /NKǨ4 %(eem۶ohM8QTTchh`0.\梗gYΟ??m4}}}MMMBO8aooOPlmmϝ;'@d (ӧEguss144\bEUUѱ.]:cƌ.jؽ{wiiiuuX=?ӑ#Gˣw%Y]!sÇ9rdhw޲M6D"׋%͚5KEE۟L`0BCCݻft)noo Zn}Gv6mZbk׮ݳgOvv6svvF x@ 1 6s\}}`OOOapĉxCDDġC_~á)ǏwvvVPPkkkWє7o -Zo߾n3ЗH&+++Ӷh::]YYI&Wb``~[?~RPP~+?ftZMM A ieeg}Fd2D200{,:2dc۱cDŽ zV^˫Wʾh,+`zLSVVNLL|emmmEEEgg'xR^4000 LJ@ h4[</""=փ`~;;;VVVoߞ6m;wƎ; [yynj 8HݽŲt,U\/DS۳֭[7 [8v؈DǿRT:rڸ\nTTNRWaÆ'O.\qƵkX͛7ϟ?@رcٖ;w?8Ui,w޹s>>R^3"DGЕ?uTG>xF{:::^|#LYx1\b#[fMff&Nj߷o&P(3g{\}YXX(((3~+viӦQ(G$t⺭(i۶mC =zh"]]]<ORd٫ϟ?߸q%@ cƌٰaCIIR$-N!0m߾=((H1::Çeeehk׮]v-00BWWLtQQUUU)o޼裏?~oַk׮ N/7n(c򈈈7nH`.]EEEEEE'O={6lfY,5bٰ+>t:;;[8QSS3k,(*22211,44{t:00P44ŋD/RRRɯ^N,X@ ЈJIIj &__R8FWt!!!,d솆6d2Y,VHH{ 'm#1:4˗ 6mBK=zN>?)FOJJBsssy<^nn] %a9vTTT-Zf?~mG/K.66׳fBϞ=+e?z3)qCTQ1<,dϞ=---k֬9yݸ?~AXg}ەbӭӧ۶mھ}{o0ڳ3LRHJJCSƎ{=}}}Iu|rĉ݆F7/_=jcc#:ׯMMM_~ NiihDЁ^ss~ H))))/hx{mڵ f|:::hںR,hwV(f޼ykiiYXX(e5rrr6Lު@p8z%%%ƍtEYY9??m}!۽{7- 3>׋#HNNR 99`m岳UTTrѮ pOYY911˗p>==]j*Bq㆙଀cڼys[Ճ`_Uttejjz9%%n#sD/!`hEt sEDDa%8w}wĉǏo޼碹ᴵpۢY}$0aBnnnbzaaafffpVŪXZZ.Z… YYYbelll;6g*b555'Mr>,ڵk~~~cǎ%X,V]]}ҤIwͥReXϟ>}:LbڮeDP?exUUՙ3gw{VW~~i4"F[~}^^go7 AIN{{{?^졎Fwww:5x+W[o߾bŊ7nOJmٲѣǏ  C'GEE<|0((諯qq۷o߱cǞ={Ə󳲲"##seddtm\;6""biiiPիXy}G}絝?3!]]PP:^VL^7 # T*NGEEqܶ6.EөT]I4qDUV3&88qÆ zzz~~~AAAﲅ nܸqڵ,kͲnnn|󍩩޽{z+,,, @SSǎζ466޹sذҥKEEE~>"^A'O޾}RKKkʔ)+WDX۱eX^9@{;99uU?Q^9}yG{ >p G0 VƦ?m>h/ eUDG#0H ;D? #@tKb$tZҋ`>>ptDDȒ ڣ/) qQ ;F^w_ONRƏ~wںHaW3vuW^۷RNN4--m7oބ`Fdzg>}TYYYbڵ#`/;ŕU L)***uuui4_|$zzzg_tiUUZĉ ܹs.ի666gΜq|||  ƅ ЅbD#<:8pb͞=oyXwww{{:xΝ;KKK=zdnn>gΜЯ$??Bl޼-O?9r<**j߾}.][PJJnZVVv̙^rEMXt3 \nDDDBBBF$*22ݽK0£G}(//3fx{{WTT -Zo>sqggg _My~<~k={¸q㢢;Y6l֬Y***x<ɓJ믧O G*4k֬Yf!g RYYRQQ73VSSCB4 ɓE=z$Lwؑnݺ`Yj^`AzzzsssSSSZZX+V  GxӧOoٲ׊W^l0رc&F> 6s\}}`OOOnnn|MNNNggƍeyڵ{phTjjjjj5kᣐ}^"%嚚 sw}^zʪUVZue\\\zd2L з%%v<.]II `244҂333"+vrrrf͚ue 05556-0;wnFzDG6bY,͆] `FG>bL&nhh`L&b_( gϞ,\ٳgpl r9?JT*ߟpp^]]`08`GGG$ŲDb\\\jj*J:t+ @UUUUUbyyy:tQzzEHAAAg>}`0 ӧO!AAA}X狦̟?ƍpxvfΜ3o޼v!`GǴ4O~~~nOd2Ҥ@d2F[dIVV^\\saֺuÇ=z4>>> E{{{RR'|"?x?`$GGABCCT*Nrmmm\.7**NSP)ݻd_˅Yd29!!!55ND)0CMffewzzz&&&Nb;wܓ'OUVVjiiM2ȑ#>}%h8#AD aMϯYII QٹXUCBBM0֭[3g΄xxĮf:::$hf27o|PTTtĉ8#v(CSSS55ns=<vtt8q!'D%K$0HёfX,kkkmmmkkkfaWA?Ց'77w=4iRff.799J;ܕ+W:u N60Hё燄X,&fl6dX!!!|>_ʼyyy$kg|}} .\3sP^^^mϝ;dIp`Dp.pT*R冇Kwڵd29))kVuu'p8ӳF\0ݻwOCQ@ x.9B[ZZ? M/Yp8A,H$M4i…^b%q!///*--=ts7qb)455`G}FE*++.r)2 ,>_z.fΜ)G8>>v,+te˖8k,߭`0/^(_ k;"JRtzTTmkkrQQQt:J8&^#>LNHHHMMt:=99911)= Y;v{ӧ?󛛛KJJ~7CCûwȫړ'OhĉWUQVV8qbjj*/ڎ`ؽ{Ν;ɓaaa{Lr)>EJʢh111}CS||< qqqh F4iR||?j*,,,vvv?s:wΝ^5cƌ9s!+: 9;; (WQQ #s}vccuhmmڇ%:::G}$6= H^^^t#!WV ˪Bƍkhh(--C :O8ٳg\nkk@ hkk+++;{!p'`hkjjyYǕ+WfΜ۹0 ɼ~:5 ;y= {{.]mGGGuChaaч'OiӦ>@ <>ĵkv۷O:駟999`bbuԩ;wÎ pYACCCׇ^tU<<#fX,k@.UUUUUU6;a07oޔ|[[[QWW@t aXL&f744l&bBBBrfh4mmmgg稨(w={`…b٤ӧO%GC7o޴/1h {!<?$$b1L6fL& fLHHXt)B8q? Vٳg .{Iz.`Тȸ(G&ȂFp.pT*R冇K3gNFFƫWΝ;w;v՞ p8OOϚYrftm>_pdA#IMM#bYD"1...55UR}…zzz摑gϞEs:b:$K.`>>ݶx<^DDÇex#Ɍ=N`ij~^9::v'222RPP(**aqEG:}y:}||tz.^xÆ X,رchuNjddxbA322d#m>`t6uԌ @T~qRT:rڸ\nTTNRf۳g>gd29!!!55ND\ 5441==2cA,w޹sw#ɓSL̄ :dXQQ1pttmii :dpF pDQ] ??4 =i$ PҞ舎42 ;wիMC^EǑ}/^ zwFhCCUV\vQ^^̙3GCt`s̙3gNGGGjjj\\ܟzy)**^eee)))K, [o޼ADWWw4lzG5k酇;99}NNN򋽽 `/1KĉEbb+(|1<?<)))--m>}卞M<A<jժ3gbXnnno߾t+ f=1;;[ ԷIII贯餣>30aªU,Y)؈|;/rl,BQUU-..677CQbZWW7j5ςwWu ã&} L$;::޻wvÇt(#7E$}߾}bKv$''nTm}NNz>^㏽l;qjhh@vjmmm߿B س?xŊ6m=8L577 @dƳgCtG͚5+00000P4ի666gΜAI$M/0I"bccttt WXQUUc=0`Ž;7o(-3:E{͙3g۶mk׮MOIIY~֭[Μ9s+Ww.--|{-++QQQA۠KMMmٲe} hmmFۆ­Gлhb>2~8 ۷o߱cGVVVkk+ǻuւ P@;wL2en>R} %>>ǧ~ӦM|MNNNggƍPۀۍp!:NuQƍC8 :L8{ikk/X@[n`cc'DG0 XhiivttDDAAA6?@TSSS^^CN|d곪{`0Ywܸqwyws\. ޝBc,Qd+-]"DB+iW)Qn*7)]RiAH[т6-q~|c& x3>3y9(wGp8pT.#!X,**65xqBDEE!!g}||޿߳gOWWWL+n޼9vXġs, ɵYjVXѡCΝ;۷W^BfΜD;=w۷olvjjŋ'MD8B+::G@vloߞ3o<099S7:@ӦMqĉ"Bׯ_oEvDvDvՈc- m۶v 3fFa89d"ȎȎO. \RMMd63:JJJ!***t3g.\fBc:? d6 WWףG6Nt钕nݺх&L8p9szv6ƍ֭C((/_Z@Zj~*jROxyfٳg/_ʳgϤwPPڵkP ;BD]vmΝq3f ٳ"??#G]Mdd jgϞ!Ȏ-ڏOԅ/^hΝN4PS7nhҞ+/;?qফȑرU.߿Q r}ZMM-::ߟw9nYǎ޾}fo 㓖VZZJ:::BΜ9\xqʔ)C틛: fC###߄zQBBӧGBbccE:t}%6߿BȻwb ?ݝВoδӏ;NC ?~,**ڷo_VYE׸?zf?zhʕ^^^iiiTTԂ EFFFׯNJJ;w.ݻ%%%EEEnݢnBQrBȶmBj°ׯ_7~+++,--EEE{aaaZYYϟ:u*P--wkȎXpܹs]\\gNNNݻ͛7nH* 77w***K,͟?WCCwޑǎ]N;|B=FW)7|p{{sΥUUUeddDDD̜9shdG!'&&֣G\4h6Yf͚5;%%E]][SS+B?IAAZz6mqͽUNcw5g hsHKKsR&=֭[mhhb?~ᑘ~z! (^2dBNjj*u~w9gϞ-[l̙p#5N1RW6S#""!gϞ9sSu@Ξ=;uTL6.Avcƌҥ]]]P4|BҥKGfddPpm\999~պtϟ?u-,,fG\4hdA~QQQGsU=ijjD;UTTNIIn&%%}47odffWC]U}Gh>LMԮ];II~mo=RzXZZeeeq8̰0w.ӧO[XX?]RRPDH UT+111))޾ pOqq1ͦoSN!?d2{  /////O 111ԩTPP8q"ud;z)S455DDD444͏=/++#W;wN__]vÇv߿aU>ɡG~~9d_|Wt ii&h%%%{͛'OL9q℥n666ZO8X(%}͛:vW[.22&22Qj)?t~wJHHP3f:tȑ#eeemll~i,98 ;<_z;vJvuܹ&&&W\233C\aaݻ}555^:zݛ &$$ 4FVk6ieHSSS[jժUBBB\yyy~jFc||<;99!)**j׮CkHNP4~xzZg֬Y{1`>+**:u&%z©G !ĉPG߳8j Ͷ B?ȸy&N!طo߰alllv{'O1bOWj s0ֳܥ Aݼ\@!~2C9s&>>j,޴\\\V\yqkٳg˖-ũGdG"[Qp8޽tMOO[nuܙϗ}􉉉=zt]ܺuGƍCnJKK>}zhh(5#./^fZg۶mVmзo_wDvˤIvQlN_gϞa~QUU-**;B-?P)//6mڌ3귅{n߾9իեȎ|-Z$++S-XYYrڵKAAAFvOtEVV ϟ?_p!$ѣ޾}{ 6Ћ233ۏ7.555++ŋ|xZZ455V\\\IIi۶m=%((h,s111TΝ;mۦbԴ{.9ΡC{AjbWN0 aum.uUׯ &ȰX,===\&=x`B(Zuuϟ?#Ȏ|599ytvŋTTT*'={6l0zϟ'ܺuKQQqԩTr^n<6UT {fΜ9FFF+V8~xvv6ŶiΝJJJF>bpٱvݻw߱cGdd$]߮]K.>777''zL1eʔԸܹs}*IM7o|i55hCC_zBK驥D{VחS$$$>}1667>>~̘1Կ"55޽{ܻwouu͛7oܸ /]tΜ9K,^:eg9::JJJҦ<==]\\:uT{$x/ޕ0@EEݝ{jhh;22رc -}F(Z(MMB\Ӻ1,lgn ** O.]4fyoCx≈{[n-7otppHIIر#>,-[Xpcbbhll,<~xdddXXuV'%$;g4GaF[!Cܿ_+ }}s禤lڴIMM~!h\;vTSSՙ-555E4Z:ݻw [ǍB]w;;L777;j_|9s B 6Jx&Çɓ':t‚.9rݻwGթS3fUiL5:tIQQٳgBR*{{{WWWHи|1#pyꕝݩSTTTVА޽{Z/ ή  >}4a„;v9hMFqaɻw<==Tmׯ_Cvo߾Ι3|ZQFݾ}[jtҙ3gՋj!!!_agq8Z(77d„ k֬A;>iii}`5?C~}||\]]1WpӧObccӗ|af 6lӐAQYYY ׯcǎ566޺u+266l6lذzjz2gޜ!AAAh;!;~mnnn$O<966m+VXfMY[=<<?~k.]]]BHJJڵk|1իy[|ɴiӸ IHHŋU8zʟb0w600F Eq߾}...۷o߾}xܹs5/.....n``,؉hsAjl }ǻw ^^^V%h>aɎӦM.6mڍ7Z?77믿H\\Z_ADDDBB fddf͚ZLǎuuuumNjjj\\{޽x躰dnjjTu1o>>K.#[n...CXcqqwTqqq+ļx{tn+V211155]l(==}[nG4++sUTT4~_~}5>[ի\Sc\X3_VZk׮l]n]aa?}ӧׯnذ ˗ǯ^z̙Fѽ{k׮5~\]]۷o_o Ev|w˗/555>b}߃G5009zhhh(f[YYM6?E={6?HݻLQQή! Vŋ111hAgGccjO'8s挱q+/Z*wC۴f))-[ m۷߾}c[n'**jϟ2dmaaa:gϖoHĶlٲzj| 8;.X/(((((8x`DDj`ccx}ꪜdGGGkkk4'4˗/={644Yk;v߿ŋCuss{)3f O>| uwwoxͭ8ӧш̎/^֎tR~lٲtѢE .7n~C훳shh(I-՛;w?^rѢEGIJJ233^$%%2bĈu}b|||fϞj3 ___6FYY:yd]KydX-[fĈE׽{]v͘1#..0//ֶ*66g흜N<Û7oN8X53fL=:vLu֦M ,\PWWwԨQO>۷o>}"##y\Y`09^%K4c5[n.**B#";4TEEۮ]ڵkh炃mllF)++{ĉ:{C\{۷o:uj[=P~~~SLA(OEDsss9NTTԨQ|a.]N:cȴܹsu&޻w+~{n<ѐ!Cv1y/_Ժ D?444O!;4H@@q~ hD3fptt3fϟ-ڽ{78t{_vѣGȎk׮7")R__ݻTIeeƍmvU>q\?...h !ՎɓwP@Sظqlllvz޽{u֭w޳gW^iii!~!;߈WsrwwCJ~~={ h:SL0a۷>}iӦf×]t ?Vcz2dH q=4'4}Mb4~ܴRSSuttUStYfPRRsJZZzŊ7n{UNTTGzyy!;/_~4iBmx޽|o." ʕ+rvxŽ{ hS\\\l'.\())P@[>##/>|8{+BmЂ lQx#nvasN{{{yyyfqׯoケg7Ђ=x6y۶mȎM`Pd׮]'OVUUE(͒Xnݟyudڹ7pgêٳgݼys̘1ȎM8q"V &&zꤤ3kVj}[ XYYP ooo{{{ `0믙3g";4TeeeXXt=,,,BCC+++iii'O\v-Z6l0GGM6'p@@噙%&&redddddDDD^vCBUmhѢ3gv OWWήm7;f|hu%&&z{{*))X?yxx$&&_~ΝBU༼=gΜO";SB,--²8NyyyfffXX50|?5xǿx񢵾G&WbbbRR}+ã8Ο#l3f]|YOO}G~=ztʔ)RRR"""RRRGl%|biisΝ.]7k֬}?~omdGhBL&!"""##ϟwpp`29tQZZsNMM۷o Pbʔ)w9ro߾ݪкЦ߽{722ĉ#G~:u,O޽ݻd2mmm7111dG&{٪V4hPAAZ9s&33ׯ?~4h+5LLL?~۩S'yyyϽر##/yЫW?~XG]]]WWWFFFFF*KW)))UVVJJJ pȎ t={8p vիWȑ#<~_|YBB֥ϝ;w<==8q۷o .$ܺu+::ۛG5BCCm۶jժȺvW?rG9rd׮]tݻwFv˗/?{l͚5ϟX"11QWWWVV… /\|nxxxXXXkJKK'M4hРK.ݽ{wƌ/_YOO+WTUU\2<V~zxx8!dҤI!!!#F+R8p֖#ܿ?,,, rرyn۶MEEvQQs=ɓ'=zTNNZ1c^*..p«Wz(KRSS{n̓W5-|@$55577Ύܛ%Ou͚SPUV}]ɺy /S\z/u|Te~zs ѯn`k>x`ܸqQQQںu o\Brб;BS ={V__.2dHDDDócbb;wBBB/_<.33pqq!ˊK++++**j~ UTTTUUX,{Ml6DZZl2|yyj_j5Ǐ,p8EEEL& KKK !l6ھz*&&NZZ(R7P|]VVUXVVd29RzͦzR111 DGG :/USsέ64ulncǎR uAw*TUU JNN!_~.f7sw4h BȧOzZ}QWWwV1///aَ}捯CSMӧO[pU4EEEBHJJJKr<m:u*!2,,,++ᔗgffY[[BSJLLLJJk dGhCdee?ӧR EE~YXX Ȏ Ëtppppp@(eyGdGdGdGU9JXXXaLMMu&[|yv턭V=zp|Ԯզݺu5k#੫Ϟ=[+6e녰VJJJBXq g;^Zk%++lٲUdGdGdGdGdGdGdGdGdGdGdGdGdGdGdGdG@v*::ť_~bbbJJJ&Lx`kue{{{uuuաCѣG_pABgjj`0[Kw-//!jYp~aa;w [[.___ġ/[^ZjuСs |X^^vZBՂR* wl p?kCYY9..N]]]jE8g]ukC>xpРAqqqL&!j)p~ ;B+wU''={kii-]؍7.\صkW11177k׮ 65B[ ȃLj%7 U{P g~w@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@vdGdGdGdGdGdGdGdGdGdGdGdGdGdGdGf`0 7ޤdGVݾ}f2eԆ^tRUUUqqnݺ5N544/^j2$i7¨NRRܹĉcbb7Çy)++X,MMիWsm_?bN81g!OeeYBBovvݻDEEk/o߾ Ύa -f;vƍz… ӦMkdd+W9Hyݐ!C>}D??[n5Q ݺuKLL}Ύ u/{ƌwy Bŕ+WJKKj8qdiܸqcII6w޽{ !cǎ544Nnٲ^g񉉉%%%IIIdG>6yG !۷ׯ!Ν; ty5FFFFZ[[WQQ{l]v%S\={ϧNJ,,, .((+;qH i&m/_3̍7V[WBHff&]B ]UdGxرfСCO:˗'O̜92n8j)S!k׮}ayyyrrڵk !T"i,ٳ !F"tؑrD''_&5dɒW^R7WC-[ݻO>--}Rԕx!5>O {ZYfu޽"===BݣG***^z5k,xf~~KF+CCI&;vfOy9|\>>>C|B u^HYY~IoB(//AaC 4(..㊵~o>>>^GGkÆ ܋A:"V TJJZ<zoƍjjjo߾BBBwpx׹)ӂ֡|Il`` ..իnݺU[޽{cǎus玮n߿kרj֭...q Aǎ ڵkG BBBLSrr2 !bbb7nXpa׮]TTTܮ]SnDEEtbggButUTTT]]}ٲeϞ=mjjjČ5JBBBNNѣGI R')<:|n|Ϟ=-ނ@k5kP5S#GLLLܹ3ҥӣGHQRR:tݻ߿ߺS#;ȎȎȎȎȎȎȎȎ…@B]\\[߿#\#ȎȎI~#ZMb.3p8vAV endstream endobj 215 0 obj << /Length 862 /Filter /FlateDecode >> stream xXn0+bBʦ>4H\-qOiNˮ$E$hI@fofkLtПO\45΍6k=nt]a0҆v]7HS.0^}C9l;97ٖa aWۅ"ϟ"rm_oFU2^-72 2Zv1/u"b6 m5qtWy?'xUg=VwGfā3Z =-e-v*;84&;@AWĖWtRM*\`E P=ʁ1 [1%?&:^7H \l䳺֌29W.y8LYZD[ 治bGQՂEx5Ǧ8x}kqt9\%20.#h&% \[_g|L]$ Wf+ZW-. x߿S!t"$x]\Lu;.;4+`Q挍Z*Eʒ$#IDO9$WHwZ_ A*M5Q'{QԲc@;p?dC$WiBcIgDm]'If;[)e7e˝ڕϢUՉ5(ds" ZpgGf90$SI6?oX/{J=*fUF9;G=]~_ ?^=kU`y4joi[@v6Q0G;W0g@z?+Aʁ>IޫG|<]Fpk4ESkFDŽNBrx, endstream endobj 219 0 obj << /Length 2014 /Filter /FlateDecode >> stream xY[o6~0Z%QvmmסˀE{PlNKaqHVdAyxs(G <o@at: H BQd( uioVpfcgiP@/fhTXj`gaxi{Mk`i` "! -yU[YT! O3l=6o.xsYd֬,sVg+V( TB. Z@Qi"Kkfn4t u 25o#oV- /4zk^:㳄w%5M#͑8S: ;=b5t{bH@CoLmkf}VyfYfBe`O/qs .e1, F9J0vTL2/Y1+bX@xyXĺ q gX<CϘ$[m,qo iB:&D;& vB[*bݢ-73'|4[#R FZ6>bO Zml B vbSp`hڕ b v -|C&)ړb`7s\ mcS\#s8iydÄ h{J{*20T&tw&Wvu他hUDk:r^zW^ifI! x5vI HG %˟cӐrXK&LTb4uL }}-f fRh/Fڝa={ɤrK5R82@uKy^.<9$/8%{h$:0ڻNj}x65>.t:#bWSQP>9IgRWf1+_3@Q&2%V~E=ɦ8q&jkW5PH@I8ߙ'xoHbe#^4{aHnMSM`4}'$*KZ:&'1! F_^n SxR%a(>C9pEk Nw4薫k: ; /$A^{Ȗ]($$/MIurLPG,>~i.Tf9`-~u:z'b!dRbgWzHcCyJY lRE*b򽤓[kr .C^v[0twF+qj7=Aҟ;>D6{iojLyؓٲfjEMR'WG/:`taTٙ+CR̚|F[ݴ'$_v'7rž$}-<ۏp!|%VMpg,7,F|vjG9l𜋨cL~ ˟=k]|}şv#zxA}R?ɽxXʰBb}_h[7=sNabQ W\t=ٞ endstream endobj 223 0 obj << /Length 1029 /Filter /FlateDecode >> stream xڭXo0~_2dqӤ-eh؊!k֮mNIdJ|}z"N*۳߀X[Y)z@'uk3 V ٢Rd'Z]=Oa"Nk_w "HIKxO4F^ѷ {}t8%׉zv p5w9 @KcpLFEVr-;Ih.q [_L?:27H#&1BnF$\Q ʀH}_gYdw"l P4 XTVpFTOͺZڂ 70P򵢅uJBX4N%W+F.Qv`!E? }Z'j*ˆ /ODAdwڒ :JcM++(\A5^ r@q7A$@)JR2EcZUji`jwky,hE?նj'A5r|rQV:TK`;kGлW6G9n/`W H0;(5Uo\ DkQ.RYsJ,:9*id⵺CFC)Dz/deuuX+`y\ 5jzv?*zЌ7͕"p<=gc~[s>(b'. endstream endobj 228 0 obj << /Length 1108 /Filter /FlateDecode >> stream xXMs0WP< c;vvtiS1Nch|,F}vmm|:art2&kbzcL)61Cϲ1vxb. 踣cK5>:":nH]qwgglz><Ntnci_MP]ҳz 0lA)}pSd\ੇZ|5`ߝV*ɦ9FӇ'b45\[OgfR3Q{2jF=GWB]®"\p=u 碸d|Y9حx [MJ aer!x->V=""p(ŧΑn&ϻ-86%iS0U-3ޢ#UsTMC:Ɛbxx{?`NtvP"9bc Lu=xAdTb'+B?I>IEPQ̅鋶@JuĈ~?cڹe\N׈}gRmXШšs dy(,%GT;7KHʊ( un"8TK%Pgrjhej>XGn@n-vH[ktE,4S+W.GOQT|R`l`z 췯:cVS;ѸAii GgT!- 8o35U#aK$ UV3bFDV5ٛ*O 6EP|,tzmJMп NbSGF(78~$VɨRiQ}Qp x\'pt'ObkΟ6>wzuЅymkg%4q endstream endobj 235 0 obj << /Length 1361 /Filter /FlateDecode >> stream xڍWK6W2RėDAMP u׏ҾPg83([A yH6I:+xy1{VdNjB$5yQdJ>?3Y:E0LE@qM>~ʌTOAL\2TeY!Cw3'i1#x^nv7Ygt==Fg+zĚ9"[zc/ו0=~ہsso'}?Syx1͗o0:|}j[nsI |Oo܍pqGUGVO32Fx8o 9jUs XۓhDmUnLdAO$\̭*SL=FZ"i=CE\V).YϨ:Kܠyx8݀3d{+kXT׳y튐ȑLUusiQ* >Bpd8E0p`sYLf1sND H߲~,7@_,hGyaE;ZⷽM~9 2E2rmYe4/0BLj^BS*kz:Dh}>7thv7am]נgUP\!+^7d=?;LqG|(JM TOTH+0ўx"(teeѠu@ -̦qZTkGPS@u0_4 Hm,G sO/iYvǎ%M{5cBmX֡BHH;GyT6t;DD꽲 tNP_v> sImKV48JC: ǕWٔπ)w-T\s,LϔC> @ Y_pAMgs fό_L}. G,G5tKP{N⸦ x{6Q)(W"Dd 7z:?b\w@E ֫ Rrl$P}bw}uS:k]j9 :x3/K^ONGG}-E1;;Et[F> >> stream xw@SWsI$pl V+Z+uTuZZjmZx}"ĪSBT 2?M#ɹuǓsMB!_?g"fXOGG'=.;; :a#̭S!w>!! TQ= 142yre|~k}ghkhޟ"9n⍵dRPP9CaptuAA՛sQcBXsS6xĸ X24՞g$Jԉ|tv=P-aܔr:.` /L:H$})3qu/ Fhb%B(e&dۼ}O[A `&zZ\CJ0ؙ+:,9׌rޜQm4TM:$D\LI!]m*IӦkR(dDT^YUht"&3 F.m*3ٲӜ^‹P3y͸Zf[Xr t1(Gy\CiiiȀ{qޟKYI *hm7"2LM$6S`kSFƦzQ]ugB>fu{(*̷BL6fҦ\B~?FѠ<`C8;_rfe*uKr+4Y"Q1]*\p2 $eܾ45H3 tu4BgϋDl0 dMD"Aİ.fꕖ%7Yux9l m_<V♡)EC`Q!K})AW߈ PY }?ll56~&fC]p [b%s:,e׋.H>7y":F*pw [";?ryhTrgtY,]Kk;'L-u6訋B谞"46[age{~;rjԐQ5b0dc}GHd:DYnq"Ȱ95ddXNfeQiݔr:o=u#HaKy?S k6/"&B(;'ܺ@,ȴ3Mciӛ[ZGf&S(N1XQ~g|.xƏ4sQ啕G#N}<~ OchR/;\kт\==SCPuBQ׮kk+Ik]؃ 8ںQ=J&F|lm %d *FCT73R44ZɸOc0_^ YWUCia%tvG[SuK'y8uE!^1kF,] k;dn PEe2Z[;.,&k32?"NǺR d:728oi:^1mR"nmCWT>Gt&B S{>L&!Lbsm1?#S L n 1WBٔrБF6!DjGYYk𨀇222,ΫGxet9\ :3jBUYS.'6(cscЁáF9\K76׶oc7ꟚH(YYEY>7b-o#B~ݏw$?!\6]uKur@0Kk;gav,Y,]Tl%?Tn$ Lb_fs,L QԷs#+ u17 CF$g]760g]H$U׭߅v >3h ʪF0A!PA"(d2YjtM*B(nP!T[]2VWUkx9R4(xJiY`'w'w<$vrta u!Z[ 1W}>4#wBu%ɚ,6BoWoͪj504鰥ðAu4?w&ut j<\?/IFU_1mr.bsuvn:-7؊A"Y8~oH$BLm(QNjHJnNFp2"lHWt6V[Sr#D5gɡj5Eu |] {DzQ^x#DISdR)~aFUTV(T22,(%#{÷ߘ<.262Xv])d YZi(FOXzF aT!$JR}u z,-51dHɒAu6qp=nੰW]ʞS}I%cGJwtqpDpB(n1l[h:O%iCFT[].i#2^MF}!J_K*&ARH4 ŸPCZR&e̛߱uC1CݺIӤjj*WvMg)s}g]|ƄʦR(t1/jD"Ę͠"RY}]͝ӧVYJj1;s1Hd҃GBFh?xG #B)ټ}n]:_ݶ.KEKǍt{VY߾BR"I$be ]mE1͜1W*l=&fyQ.kq}HKMKV_wK>yaV/;t訜tgyG8LhL&L?gs:M(G/|ASAN {U DPRoa5k:C;)%gc# cGt Z4&ƆϘk7,+<~w{mK JTjjl`%’w\+J3uAk^^JۡLB+Cj֭EuK w@|V^eifojQz^/*Y̘ʁTa(F9.>~q ,rz$7i>2vܺ6ʩ*4W6zLU4ҲP!JJfqb4ۚ0tHT]]_P.(.(>W&C7o߹z톁6ʨk7NVj3H{q61446U]wL ꚚwR.\laekfa_RqA[ + s--D*y_p'%MFpU|>UY65,bqKWmWA-=~꼻C.b x&Sc#:aX5Qݨs;YKeҸk MNwh_:>Q`gή݈]078}\UI[Y&+p;\9L B">Cd҆ee%5ՕM|Xamnacdb7׽x+yZX]Yj8z\3 k#-mO?-xgicU|doo`TWVdR&̒f764(T h7bUOؔ@ TVUx7E"PwzO +1ſ?fsoU#+47h)BZ:"L+yZT_UQ.ZXYZ۵I7olxWRTPYQ.hi035Ԡjox Bk`ԛs}VZ|N~cɭb`hj`hˏD&I477ru4:CKCbqkkZZB4[[T [_R'!65P_+ɴu,]:CTJ)d ]]=~cD,֠j::LM!dlbd֛YE"!aC[[GM?t N}}0&KdVl}bed Eadҗ :,6_KFt&K#t!}(4o:[Z!`׆ 4A-X2dpGrz(Hq1pօXى מ>ydeӏpr::L0:9pplf?E~u2͹):0Eo?hg: F.vB8,-Sk0!t }ݽ:#/66M LxK B!r6yz=BYnҳ5kz7;ʁ8gbbbFi),+,,Օ:;;?~:oǏ l;)e߾}vpp믵Lz(۽{544g?){fAR~W777 믿ݻv<5odffΙ3F$^ɣ >\unn.xxBR)ǣoo=M})++M^Rn߾zРAoܸ1--ƍfzWeddD+VMM=ܺukFFT*uqqYr*e_uiiq``ԩSa@o9ʞ+:8(;-YOr@yr9_mNCa#Fȑd#zJLۉ:#x|[!r9 @Ν;vȑiӦD,@霟_:@$ʤRis3"(JłL0b c,osIT*D tN UV'':$EbihJ[Zt$ Z0$ |TR+fͼjnn&HrBZd2L*R5/21LF+tM j.ɤ-T6E2LDRT*#IZď~ئ T,DrkuuuWY,*))_\~śn!ikG*xF9---GQQ};_TT:::Nr%G1mڴ3gX7֐cNG- !2*#޳sɓ'"l\r. +fHeT"svvVg/"5oGLխZs<<)*Bkh6r={~޿ߛa dviX$J^=i??yc`[^)=ՌVJ%H5@!!EiD**l-*'C*CUW mY|kdC/^9vYD*^r[5 ĉ^MMMFJ"4L&k7 -9Yw7&ִo1 #˗/7%""B>ehhxԩǛXYYUTTȷ:qĐ!C X v(RQo;ܹsʕӦM 9yӧO&$$Xbʕ= ۷oߥKX,6oѣ۷okiiῶ{~-??߾}_2I& 4(777..u۶mړ&MP,"<<|,Ñ=B1̺+D"@ɓ[n۷!駟.\pʔ)A&eddD=={{{|ɓ'$kժUǏǷz/>PMueB FC__T*B77O>}_X___IJN ?ֽ2L&&O,ɄB֭[׬Ys1"pBcܔ|njj_ 6   >\͟T]k׮D Je2---/\0sL .\`aa1p@ :?ׅc_555;{{{,J?~J_lse9+ҥKO"xaPԺn:fVSSd2׃>H$)4ρOrr ՕsNpp HE|Ǖ'NăV#GL8166 ŋϟ?|?cJJ@ hjjJJJ3gN?lٲ>==](޽{wݺuj>>2߿mmmKK˗/_.ϖD"-XCK2wX82ǩq… QQQׯJׯ_|1o<*?zh"?߽{W*:88,[ӿ@3uԆgbbdɒuֽ~e:~z'''LfeenݺoFyܤR?,a#zZO]5YOo r@ Bt9> 3͐,&b')zٳgH> 4'_$@CQ!B#䰔= 0ۻE]kxCzCFEE(k[huzz%J5jÇE"?z~ZٙmUtwvXjժӧ;;;_ztÆ O2dǃr۶mk }Ѩj޽=sYYو#I曇\ښL&kkkO8ʕ+_|ŤIZZZZOο[UU\r\\\\kxxw2W_eeeݿ_ÌEoGyܹ6l6]SSfEFF2`D|睝544,--CCC:~ >G4sJңGZ[[S([[C98ݻwӦ4N{zzō=`0ӧ㥫 d2@[6[}֭3ghiiO&&&'N0,((u޽9bee%GqL~h4.tҦ&y>ϻQTKK˰0yClll9rgϞ [[[ .J?궟2 ! N8gϞxC믧O~m&7nܾ} R:#>f/e{H$/_^`M駿KtΝkhh^x1;vlΝK]vɯ:eʔ?s̘1رcݵ%%%vvvcǎ ڶm[uuuqq%KT^qVzϞ=t:}׮]Nt?CBBV\>uΝ;|~dd/ҍ~ 2&++K [NرcG}}˗^;v짟~ ۸m۶Ǐwncƌ?KJJgJiӦ3g3fذa\ogKgeX-c?O۱cG||[kall0H$ϟ.**!HRra|`iiyEGG'X0 KMMuwwW\_4z5kL6 OOKKꫯHݿZSSS>6lؖ-[&N(oɓM渹UVVΟ?aۺ:7p@y ^ސ-Z__?++rpptqqdBP[[[  u &\reҤI=~?mmm?RQ4|~ʔ)w֭['Ot͛SSS_nG;v妧M]]DJ~@ ޸q@(:⼆X{JN ?G9<{'?Î;B?O"?ׯ߽{7̙3HI7; v^FhiitR/9;rرGDDBN 0֭[oߖO)E ۸qI;~i``^\\S庺fddtu+GGǤ$D~R:;;'$$OWlWbbWׯ/X… <o׮]a7'''ݴj*ggǏGGGO:Zz?(?ŋxo޼s疔_4z7Z扵. yQ}z[oիWGGGyyyD3gGGG+033sΜ9_o'ֺq^k+))i߾}z C9ammm}} 644Yyb8;;{ɒ%i ]ÌBCC̠7zso=z&N'WW pu덹sΝ;v%LoP&^ @ONgzY9} Cz2͇ B!r @!B9naɓ'RtȐ!<(oy;<ñoڬtRGGGww˗'''CoS̀w'$$Z늟=<< ) !3j(}}}GGLjlU>~>3333fٳg5M*_߿ojܲe=~-44111sss޾};kvJJJ|||xx8سgGqYrJ''v_k֬innV;vcdd<۷geeΛ7/66V,%BKvڱcGQQĉ{9x ;tЯzi{ )**͵O~ 6޻w嶙xMΝۻw_w}⊊ @ xϞ=#m2x]9n޽nݺ={\tIq\ܹs'MWZZk׮ϷD"yɊ+Ǝ+OLKKS=1aYrg޳g… ۷oҤI nvZ￟;wԩS<v_dɓ';mxWϯcǺ%%% M6yZ]r%00pӦMgΜts'Nܻwƍ>_Ν;[XX$''O2pj {ڵk3f̐_/_>a„iӦ]v-,,رcsYhӧ8o5a„{zzʯn3gΔ/RVw@@ݻ+Wybrw522R \.VOO$M;MYxJddCOKKKe=9vتٳgV^o%%%cǏ999G fff/^P9\\\=zXMM8qڵ&Mjs'NS[{FŠ|=<-Zh̘1k׮=~8k x<ޱcDŽBall|luPAK.7~NQ롷gO/Z[[544dϯ+V 8X,yNOόs0&ֈDbV펛wx$)^fƍ?Cݾ}[yMR)lECBBN:enn~Ց#GgWt)S߯8斘؍ 0ÇwQZBB‰'>coo CowY,>hddCy:>@ݺu룏>kѢEt:… eee7ȼJ//ɓ' SNBN'խ[oo߾-(x x׺w&LLL|~QQP(411A GIR3}b))++Kyqʕׯ_oM>>%KT9 80$$$/// &&fРAG}Zpa@@@nnX,͛ׯ_N'/99y˖-Iq?v!))鍞7o4hPll+m&9Zti```zzH$JOO_ve˺?)233ڬ0t_~E~!4v;v(н|򠠠 y)k7nLKKkmmmnnqƬYEFFF7oT6͚5+))Z7{ .nj;f̘G BPXXXx!˒o{̙׷y$C$+"""--mK!v{{ٲew+WO>3##E\`l޼?pvvVdook׮:@Ix2]611oҥK{_~CzzzDDɓ67 ?ŋx쳙3gnذvaÆ>|xǎd2t'˒svvtҌ3WZNr8e˖)^Ss  TҮjϷݼya„ ;wܸqÇ aGQֵ':%%X,/^r &\p@"8O.]ZPP sssW^=o޼Qv_m?GDDL>v卍+V ܨӧO ϟ7ʂ{aqb [aMx B!r @!} != @# ңv6}!B-H#GL0TOO?%%X,V75r=^uTT(BYn]BB/_VVvi''׿ZT)h{SAAAOF)ttddd~~>N-^uJpU115xfs(r\ggǏwNLL̨Q#"";vcdd|C?z|:ehh<^^^:::QQQ!9y:a2@ ([nnnT*2,,L~! bkk{Ŝ###i4Nɉ=z4`0ӧO|![[[ bmm}QŢaUwt?޽{ɒ%۶m;qӧOq߾}x~嗋/Y!>>ݺu%%%{tʕ+6m*..>sãx\|y6mjhh駟/|wiiiccΜ9#9#rw@@;/_|U<رc?Sxx8?vضm;v][[[RRbgg7vؠm۶UWW/YD/?uNժ; ԁ aiYҒ4xp\|x/OaXgΜG;v)兯sݕ+W޼y!4qĵkN4(&66׷ Ff͚iӦiii_}Uvv6BHSS3??DٶJUa+>￟2eJt77[N<{ҥ͛7X,V^^)&&&|>_'NwŖ-[ܹeVQeuuuL&~=r+9=4ҐH$'N4<J㖕122jiiyeE TWW# 555fȡm#HBk֬1cƐ!C<==z6h*&]SSFͺxa&J:LK0Y17VEZ 9j}/L&oذƍ*'Jy<^<޼+RQ5et111111NNN!!!bdP>~*: qobbJEEvf}}|Ǐ׼}A)++rTzkFF...AAA'Nؾ}{9!!}}bbmbbWb&&&:::SDVQ͐ͭ .cƌE"QjjW_}mPPPFFH$ \bEׯ_qƴ7n̚5 _vDPXXXtR<͛m=ږ-[ܹ/NHHhnnW^MLL_Q'88ڵkBɓ'ӿdHjժ懲NPj{9W\  o…×_``P(ׯ7|#F˗ץƁSNmѣǭ[fddHR+W&Ls΍7>| ((H~[te2Y?6nܸ_~%88855U*]|-[)ȑ#nܹseeeO//~-000//hƍxy󚚚Ν[RRbnn~/{E]/(..655ݰaÌ3:-BYUtC^D"144x-Tw$<>/33:>do㯂lss{Bw7:Y5@/} i'<rrކ?8r-L1L=Hr%rʐ)P(6667nlmmF=, N}oo##|>̙3AAAO~Ϳ^w9 ~wތ#FrDClll(#GW;z5СCxȑ#ϝ;ZUUǧe!2a4N{zzō=`0ӧWVV?ehh<^^^:::QQQB4.]Iȑ#VVVP "; l...T*UGGg̙ `0DX,F]xqȐ!t:&44F}>~% 5P=o<<%<<֭[w177={&%%_diig3j("BBB-ZԾhX:4(11Q TUU-Yf;::*L>_966bEGG Ls׷̜9SuL&3119zhKKKYYٗ_~em466?+W]|Y^hCE&* lߟߗQB7D&Id89(G,?~xƌ~~~kVss|&*lHӧ̙hwrRi) v@^.[,,,X 'Yo:C䙨n4P4sX,VJGGH$A$D"{9D"fLg||ݻ3obŊ>)J; n4PTB@ D7p/Gb0QUU%WquuU=Sgb ~4cccHa*2t~ʈ#_i?h4d2Eʕ+R "5+:} vjȑ mLX!Hg̘! sP(LNNߵ>u~[H1+H:cƌQY*2sU77۷o >U///|׵kך>loo:uƍ555ϟ744ekk& lmmթ@*2QWh`^z͖>ڵiӦ W..&&&V'p&666Vȑ#$mAB?!Tȑd cǎ隚Fp~ҥѣGkhhhiiyyy=|Puz~~ T*Jutt?K9x𠅅;BDE_u={J׮]0a=z4<@9ΐ-z$ѣpn333sΜ9發exaʾYx$}+9=4xYϤ}m۶K,Yhѻ0LHx@5aFFFfffNO8O>)((066ꫯV^2(>ȟ9;wܹs{C&!B9 @B!r9 r@!B!r9 r@!B!r9 r@!B!r9 r@!B!r9 r@!B~a=3@Q2„2 `1f6o@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r$$@r$$@r@r$@r@r@>J)8N)51N9j[6% endstream endobj 241 0 obj << /Length 2604 /Filter /FlateDecode >> stream xYK۸ϯP9PUMkk*gkVvSٝͣ>ТFG#MD)Ό}H%4LfY2E"?\]zS&3c*$UlY^fqU3{]m&Zi^Df^[}s&%1~fUCűo`p ~{>8 5L./rFdrэt[RI%-a&pSShݻf SYV嬯,j\y/ۧY)c'g6 zawn{<{42[7&2! pb+GlyqqQC[p0;-ۊ:Q8ʴ77Q/Mc[$/Gl&z1e>,U+eY6/tl`kYl1&xq&.R^)˅u13¢U?`qmfheqds)5Gh"ZN"Ur` +7:t}Զe`lꨢ`_-9[tV5kI(v<'q(c] I+[*gwE]%C%y`wEl\D5Q+]p9 IVQ'fa؟ҋ{T:No8Cɣ@3xnQٟ\]5zBgTgz}vhֽ4Y /hO# jՓ}v+ ICy%4c8s…A־?m; ۻkn6r!kQ6΢$.\Y1[kJġGg$v=\ zeZKohNp qf:''LA*CM{_SՃfAǀ&s;LgSyռdSP4cO^%U=y䯻nubƽKpx}( YLjY Xc{[}g2}T<@:GruɈ*j=!J ϳby c+HA%ɨVqeX/x3!2h,2.ݑ6=ހEkMa*P=ԛK#k4 $Cԍ7< ysO$Cj3O &g}8%EC]j3g88h} jft<ˏդeX1ˆ=_{Xnt. t`{}ҕD;Ɣ<MP(Vk] R:8ѵr6]G'YpjIЛGWKPJ aG =:*S{Mӳۍ/扚]T pω bp;>G 9R*7X+rUyV#R~ +U0z"!<\y]dpO3"K-mZ!2x^!I"( Z(@ʕo%\+ -}I"8L} oBeCd]okqSxyRFJk^KTLk44R/xXƍdj;ahR[ܫbď3K;L ~Y2!y3~\k3GC,vYkp%`7W/j%/.ua !RS@0 d;PElrv06 l7UlVĶH-j8q@-,\g:iNpW87bfvu%vEAM(_q%5U#XR_wD?Vtn')u]<从~p&\}C"qLӗ|^ e}4Zd~=tRgYRݡ@R9ت& endstream endobj 246 0 obj << /Length 1124 /Filter /FlateDecode >> stream xXK6P (IMc"za.e=~͋4G.8~ߍ/^_ FBJ)Q%XEqEY8:#'Jt7]3jFn;t+?Sխ .ewu/1e3\6W~(?ǿhX!C>[l< =&R7QpQD7m{@oQĉ# 9Br;byXQXSK(Z" k_y'2H[t :ER (cnqУn kh!c|YoY(a>9'rqdHPya5_r?RQ'M 0y'GGҙip6 TPvXk0``mW#.ta+U'aUVH,JY3~"B_n:jLD@luQkL]oP6hI24>Y`i #)`FEd2׈)U n!nCnAOVdijVZ{K槫A[KT+du^VbshBUBOZ(ydQ0zP)Y)ܡ WJuVzfv$XLI,+\gPLf1am,YUM9wtc2RA[!J&rGsk=L*9x"ss"jr?]u:zV>%5u*.%:@(]BD@G®XI;Y U+m!XVǣQhD") %Prֆ|B[)69`JND.Xf:jxS,?} y' R'9^A/> stream xڥYY~ϯq߮]ERm/r1?Yøk=uWgIGQ:z,gNG$MQl92id娬$MѬ6~51~:;LyV8c\V%x GeϊV4owBN 8 DwBX -d)M[i&zq7q`}7Ȍ onj(Iܞȳ';+VpXd\ xoH%3T J'6 p#L2"-Hd2r<#1{::d -`i. w-o G!︽=fF+K{bY2ӗpcboh5R9ߋƮE<>򤺥Zs x5OMA ͎NraR5(jԖJԎd J)rt4͚1 ev25/ FV Pw hĖ S|9}q"1TTޱy-)O _vUN x?UIuL6 ETGzMױvciY^ wn4KHN %FyP:LGaUoIўsnx+Wc?Y', M:=-Rk7b x%\X' ir;!`t 4DQ) E|L~78ss/gߑ}l0KR~ ,X~/g-w90R9pܝ\6}4w}ˎ-3,ic@nA*ۆm6 ezmu8sT3>rw|,THqy?ͬyO:z:Ui`o1 Uqr@Ey:L~(@[ Vn.˙:AODR,XM VQl,1U9.|gyRi0l֘ AI00iR ql4Y% #ZOt<ǽK;77BU=n46y-^%o +2"XԐ<@wrV k/&<La2.{m@ %Ebj'(^naC_iMY/ u7ܹYZ9WͳΊL9FˑP vQ [`7Gɾansǝ]II}ݱ-mhcL9ݓB<il%fޞ.t\O8= S_ZPdLȂ[ y[`RL0"ͼmbˋwCffΥ~V|h\j՝b5gՋNQ^Mp-]wl{ğ<] =R\f-U9QF=qyzj%X-|"U٥T},g,/goN!>>##YVY>Qna=p`d%w:gyAѹ̊"pp ʧ1%)A=`X.0#>x WU ӱ2zN=%M&~{ fΒr<&NKdp9ơǾ-YxqOT/yX|ԁp9i<ٿHwP endstream endobj 257 0 obj << /Length 2064 /Filter /FlateDecode >> stream xڝX͏6_{HU%/=-Kwz较'd&iiQ_>qrx胒H\ro6w_}Y(%kbhR-job[rV֩eR]]; ߰0I+CO>˞x#^Vkk{.>)ț)E^JTUDӵj3/2OGx/X#<CX}-v{a ~1/:EX򯹽]˿y}&(8+akMsrIh['vs!jkE%t8CE #8f|cxȺ8=wvQIk<_žҭFeպ2f4nhIC/l~ݎ(Wڃb;bZaT/K+FWRЩ0nt. ^ih#XY@p }n5_'T㜼.q4 }š~NfkD9(5Lf h:48x54Bh@ ?]jD]5cWBq>Кew_W|tHp x %hrYE|WmuNئl͔ӽ0[&gㄲ%\/l pybrū2R 4E؈bx5]ByH]XwufάZ_EH)9jOBu ^ߍ,Aj&ߕQtg & ,'sP-120=2|\!gԉ|d GTn#N]F^e-Ua I8ߝ}-bEh-x,Lij'qNX \>dC;t")T5Xeke,UG GwIa0 gBf`Kd xs6Ơ7Kzˉ*"z&߫G6 5/l`2 ZC̈XҜ5>9Ȉ@) I^cGĭrV>ڵ4a*-qZE)LW \F 5@]} hܖpAp|eۓ1>*\gE$EKSk7}Z|Ƹ%\)z 4-eq&6E5lEjBH\ncӅʆ}o"cA ^"f6 Ζ+8TAGs_&pto3eJR˵@П P;cʸ g|Lņ3:KsۉDI0=q 2AS~NOl]LӪ)౥*3b{8;U S؄}/9ܾ'+ Ri8S'bqΐ|r$ϖ#ZLFiM13~lg3 %6mP(|C/Æ3,aX3}`@10wP)֖ȚWr>raM#wElL e쿕]qѕw R#Ĭzzs^ HZZl)/>엉d,!!j(2>Sb}F>+pėKrQ,3Ph8IaQ2_#D*LeVM?&*"#24z ^h t<~@g x endstream endobj 254 0 obj << /Type /XObject /Subtype /Image /Width 733 /Height 525 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 42880 /Filter/FlateDecode /DecodeParms<> >> stream xwTW7.ޛt"Aŀ% ##,@{7&&6@ETPbW:"K6,, 6q͛73-w޼B!mo𕼹"IX#a|yv6vT5kyz4 !g"o^ @oP\$bҽ5^HL^1~!DͭA^v-uAÏktonD@aÐHnd +---Y`qJ_(}(/gL@K0 ͭut&OrLzEV]ֆjbc48B#\)A-}DOֺl)'Fn?Du_RTO \rMxii9x' K3һR4(dNyX&&!{ȵ[PП`>ŲxDono^"`|ȩrCU F έ%9 3xdEԺETGTGk畇2jDjkD g^ғ?"ӤT1UҳVkYK0Qrn[kvMZ#DQz-""")ͺL7j(0˽Y~pIcLO#(k>w7Ҩ Ş5XUEe(`cؽP?|s%Xg%eTmo"7u ,g7hkmI3i {0zA~f2X:)9 ke,[_LTC` ,aiКZZ2 GH80$&M4ե+E$X$QCݐbŌՖSg**uE{9OدDwxN2N#/N-e%f#]]Jòxj{iy2!1SQSVü ϩ sm F4#UI{YXq$UVFdBG{~k:r\sKɛ/S'sײVty(d O ƊFPSN!Y 2jLM㣉9+<8r8v&T7ˋvb?t$ T&6Y=;yQb%rv xxKcMKc-Yږ ir|cU)+<]BM9RK:j;ae"|k洿ǓN]U߿[!:j%]އms:d.!A5"H=.BD+H0E($2\~=I*RUÇPЩҲ%nKEOSiO(xOD&)Ɨ LְeZ[KK!Ywԍl-J{~f"֊Hm[yबӚ~aM*)4|*,&&$e5@V]ni2eݿGe:#QBM~1B!C0SHD&KЩt9 {_5r?tA-&3zsҲ1Ս2U$(dE~FF5"LRR<#(Bm+-#J/A6M4{xaB}Qǝ-"c"%a;t)"+E@kܶ{g 1W$6b/-Ⱥs6껟}8moWBMJ׶Wr^7o#п%=+QW{-w杮r2u}v򫚷2*暴BQTʐgj);v$l5iIp!y-nksRɜܽ-Пok$ĨLIm9W!nWDIb#(_潽x㞸mo'8ZL}Y^@I"v9F2rnۇ/ K),xHOH(K@K2{G4LG]'|&*%.Ⱦf0bԜ{GDFY{L[AGWO\֭tS^IvZot)VVzuezqUI𽃑҉-~R4>\v%BdjfȿuGKNrxPK^7jx4cYߪbKF"~{$.%iz87,2gQ\rшwpG˒7yD<B%N$N.'}N.2.4_DдLso?O5nc!d>a)o~.V1ꬵ4W >yErHED'ֶVi{Z W3c657߸0υ8G$ Ɔ ’<#)T*.Cq9-5CR4 y,$K$l]S=m&mYjƳ1 un΃fy7MVǜfpynME#e+o1nnnqoG$̿#e~?F$x2SAy o.wRsɠ_ttu#ێWm !YNZ..S{jp'"C&H0:M){-[XLf[_;?=Hʨpm-Ma0TԔ W5sBbTII Cu&ƪˬDWҮB rjU/YuE͍LuC! uU/j9umMHdq2TӧXMuEI Cu(YE~vks#Cu$K"/D$d˻e!u )9 qB}y1Feҕu% Y IAQW~ZRN7o/Ru1a,QN iߏ_0 I,Բ1L*-嶵45`&P0Df(q|cUYscFPrT)"`*7>vlB3TtRm*]I;d #NmT̩lm`BcRem\"*F&KH3D!)uTWEbQh Ab4V# J".wKEP4TsmS!Oc"XwAL\N>WN7_DITi:bT&%\ CA7aT)UP"xEt9bF;tv%T)KXHEH2ʺHY68߿q^e_˷w^` |4>I;".|aR)i$щ'8͛79T) / Ht2LLBF(4&Non/K!/; )4_ZGy kf-HiT=yQxj` ׀ B@0̵kBl6%|2֭ 8@0fðy@/?6FLL  K /ALL K-fϞ AK /%_"/a!M|Z^FjBdd~}!=?-yIvzBvvv &&&N䤢"##*=jnn.//offvor or---61gΜ133777?z(R%%%]]]//zae~/^1cG htߟ^vSN_zX$444(((776wܹƒ\|!gjǏ8qbw˗/:tpsGmnnظiӦ͛윝]PPzEQpu51cF3fAp%{FXXݻ]]])mFݳgXgo߾‚L&[XXl߾O?~iii9|eP7O-EDD퇆Ξ3gBQTT /d|)))2lnn~1a$d#@ veggGڵ 0*r+G}wɃD ^|ĈYYYݻ8x񢺺aw-++]tYYY@@@\\\iiikkknGK.upp8q0Q L>yi,,,NKJJJ^tf}|[FFFjhhܸq֖%!]?iii!aryMMMGٳݻHL"8qbAAĉ{иaYɑ y(2?(//[pWY#@QQQ%wrD7nܘpo߾=sL}Ass|||~Gbִiwرxb[c_V\In``ZYY&`Tng̙ uuun2JKŊo߾r{{͛7?x𠭭mذaVV?L4M"͟?!!!=ɓ'WWW/]H]]~g>|gС!]]_6Q@v-[&&&fccs \@WY#@?ix _'/6=44˗&?3{cbb̙X@3@PPЊ+FgHꣻt8FKL]*Y K"@^g4{l9$ ,苠@/?6y /-bO%@^y /^ 3޹qܾ徸0zK^zF۶mp`*< /a B_h@^^xqɄ/^%RRRÆ 7n̙3!D]kk5k"""Z[[ykkk=zѣÇC^>/xp?VJJF7.==v5gggFyAʊNdUUӧD۷O2e$N^:''G777kjjs$///&&F,Xp9_XXX39s())d555v+yt/%%RЫ?V.ާɋ`0zusr}:> Ippp``  b͛sţw[N"n߾=bXSwVf𒒒uְa:`[nM7.33S[r'=:;;fgff^rСC߿$oBp8NNNׯ_'?S!APPЊ+Fg%_ Ʉ oE544888ElݺU6KJJ&MaR"uu6HJp%%޴B_b 6((HJ>Gp%%gӏ?a?y |;v(++ݰaoyxx6nH&''fжmƏwiӦIJJ***=ٵk3!/+[~~V^M=zynnnbbbccMx[fee 4hĉ~~~˛7o233===qqqk׮?uTxxիWgg삂Ћ/vBgϞ=u?>qDOgeeuU>ZMMwٝ;wƌÿ?CL߿Jl4Ϟ=~zZZZllwY$\]]I$DJLL$Ơ|(@"~򥞞+JKJJJ^tf Xv |Q[\\ o0/u###n;wSS#Gv8!gcc-L"ry ~L8`ĉĬ{9::D?~ϟ?ǧo.}͛72dсJ|K@nnu:xܸqDccիWM6LoW"!!rJ|#]rw|. 441&&ͭg_~ƍgΜPWWw-S(++߹siӦرc$7Ass|||[444Ν;{ ?Lӎٱcx;3>+QQC߷fruu 8 yIoqᴴCjjjnݺ_Y;7oߖ.]ZlYppСC\r a_b @t4 V^r?tRooI&uU>a呑cǎ%H D׈'O֭[gff&%%%**0iҤ?'8zADDD0 322JHHf.]F2 kk렠tQZZZPP̙3 &//O9Қ5k֍7n}vccc2,--=~9ss1 ;|PP>B'OZFFl}܇mshh˗/G0L!v>_ C@?!>y."##bŊSg_|@ 1quu%NN}y½KRRҁ -۶m^ zKz&k׮_i  ǎ tOgg $ti/_,--p8#FXl%Y҃n\7KKy^ݽy6"/|xy6%/ܣ%@^ ȗm钒b mHHH|Ox"22xsjB|Q .$^:;; 4_'gϞUTT0 nwrq?~>y(B(++ ++Y>r}}}F{=/111qvvuvvF͘1w.H|EEE#G8ǹ}6ֹ۷owkM?E>~8Grr2">}RBBBRR1##4FM2 }8WBŋ-,,TѣGwyxxHHH˯XwVVV4 y NP(gϞr;C&uuu;vm$\N]r0O333 u|\.˽u떬[)<<ɓ'Ǐ?yg_^v !dhh˗X,ޒ)S-~eUUׯ766>|ܹ,UUcǎ544-\ÃhD__޽{MMMxСCwUUUp߿?}t|Aݿ$%%iiin7Y;nW0 .466>zhРA7obwnݺu\=zmmoLTz=yv zMOeoo;h&&&&&&޽suu%f%%%^r۝鲿$++YYYd2UUZ#F&LZ]]ݷo⍤XZZs_|*677t8vz/Y 1nW{yyM<㣋  聠+V+7}كS9$Qtvv!_^ZZ~ؒVO{ 6iӬջBOM6m㤄7;)))_ ;{l_[[rڈĘ \XXXttVtt֭[?z?r;vApSGr. {=}}}xD\'\RR;N/ T33xJ;w\zJ/oݺechhaYbb"q'!!Ao|w7ROՔ>2%]}8hbb25Ϻê]dÆ 7oljjzՂ rccm۶솆K.k|||}}}mm7qx{{{xx477߿ݝ%`/x#iԭ'))|G|<ޑu_$88xEEEĕ&...OvvƍgϞuwwWVVF 2$((HOʕ+dsoӫfϞ]PPvZbo|6ROՔSHHȆ RRR,--}}}@]_رk…%%%W&fEFF5@p=|u='/IOO]TTo <_./MBHX@^K /@_8l68|3o޼.uuu99>@gttt$$$ 9Ϟ=;rݻw+Tŗ/_nee5{ǏST_Bxx'm3lllO :Kۃ;s)Ey޽{,Ydɒ%Ktw2___ee{yy,+22IYYYEEeٷnݚ0a߿bEEE988())ihh,\ _gmoohjjzivTUUeeeۭ4::QIIR1;;SS[[SEybXvwwG6lXNNNBB_Y;vزeKNNNffΤI6l댌 999//yyyiiiҞ,%ܼyc͚5yyy'O z*NXXXPPPNNNڵk6m=w۷C$:K>!D!ix _'/n›R\\gϞocک377 p޽C⳪ B~/+++ Jtkw&LzѪUvW $862 #// %:::44466VT?8ÇOHHPRR(}^nwxPPЊ+Fg؋ƗDEE={/IHH PVV?ɱX,555>7!^"*>]]]oy!7CyѼyX899w~ff|n7|d2Ν{s'''wwwHJ/ٳgB(55uiiiiiie{vŠw޵ 8%r3u\ ;mmm$pzmm̞=]0%_͐;~8ӧlwFab!x)*K趋/;VYYYCCcȐ!k֬FK|ڵk=<<޼yw円 //(tCBBBlllZZ$^sNss˗_rB>m۶mٲHJ-*..NOOK|!1bDy@y ..j_߼y,]]ŋC贿dBtWYY A :t~kW^PP'N@ǀ?l߾ Ϟ=?~M-0@7HHHܸqcѢE?~lZZZJJʶmϟⲳ>|hmmmkk =%_|Z0@^! `K /p\K>k֬Yf͚5_x‚Jjii=z(+r N>meeEDEEdcǎ}0̙3Æ Rt:}eee,ʼmii)!!!))蘑qu{{{FѦLB̌Bhii9rvϻ΂ ӓ`0 mmmOOn-{7n,,,***׮]Kڶm[DDnmmKBBBN:U[[{̙͛7_prppΝ;_|)--l2a c=z-[/_׌]hѦM/\?. «zeKK@}}ӧO>}Z__nv=+((JJJ666.]ZMM">JIIᝋ/?"6nx}uu'N444644yɓ@τzxx?~~ O>vyŊRRRx͛_~$}&/|}FFƽ{.533/sNpp.JEݺuKp;tBBW Dee%ӧ=k]`>uܹkjjRT|y/~x̘1|}}w#P]]?Zredd0' /<jÆ 7oljjzՂ rccm۶솆K.-\Pp;))))))>>>_enj{͝;g$%%q88WW Jcc皚"޽{IVVaw?IPgQ(Txռzƌ3f貦#%%5vXٳ,kƍAAA;wٳ7l0mڴ֦hk֬Y;NNN!!!6l 02OPPP@eddt8/@τvvfn*M X?yɓ'OܮpРA׮]-!xɊ+[(QPP8w,DR888tX^`>aʔ);w6mڶmdrsssIIIbb"~n{ʔ)(:tYO<';p8]&GFF '}]VVVSWWǗP( yZZZ@gbeer;or~:>iҤ{ڳgԩSi4O#A7 ݻwϜ9s…F*`llacc!&K_~F1Ԏ&>n%hjj"^|rOxBHCCJ:|ȑ(%n̙cǎu8ȑ#!a _ ܿcر!rbbK@k޽K,IKK[dɒ%KxttӧB...W\S^^Kcb444.\{beb"22IYYYEEeٷnݚ0av+**ai׎lXybXvwwֲ׮]ݴiSnnsn߾ƟB8~ Lf/刈༼4iiiOOOaڱcǖ-[rrr233utt&MaÆׯ_gddyyy5o޼f͚'O_zh',,,(((''7,KB^^^G3fE P(:::@999?~rȑe˖=|d͛\ƆBXM6ܼyprrz)QxxP^w^>> MMMo޼qss#fM6->>~ǎ-"m˛SRR~ᇞn:??TS__Yf}L0`(**f2ٯ^*))?\2}twU9/>?͛SSSg޽{ҥ"K/("k׮o666(p87o\f !AvFy)www4|8Fɓ̼<11۷+++CXZ^d2!:` 0afllكNKЙ޽{JJJcƌ𐑑|$ t͛7.))yȑb33OBp>f333… KII(ݰsI aʔ)O˭[:pU%RYY`0:UXXxQ%an1{קP(rrrɁ(;E׭[!Ё]v?}O˃1fΜyY֨3f@ /˅1jڽ{7BhܹUUU999Fz c̞=`˖-mmmDaccҥK !yIxxYg͚5k֬.~12~~ NP(DauuudαcǾbv̙aÆQT:>}v̿>}RBBBRR1##4FM2h!tE333 uCg_ƻҋ/ZXXPT---8Qڧz ! --k.s=p͛78n:]]}A|I^`0 gp֭[ړ'Oי:ukAAAMM޽{ϝ;G 9uTmm3g6o. ޹sguu˗/-[&RAAAaaal6;??GݲeKyyy^^񚱱-ڴiSuu m۶EDDV\TUU{ ]xҩGfysrrcbbN/+)) Z[[/B41AR y;z 񲢢BRR6V&&r6-!ڱ￉Y)))D;)))ҥK\!Yn]/?ܒWaX~~>CN>=wܯ ߫vE{=}I=qㆵuO~-ΎiӬՉY}ߡCL&NC^~o NZZڷ~ۮ hzz#͛7B BxxxXXB())i̙BZw),,,::ZKK+::t֭_}4A'槼l6Nw}ZV$''WVVFGG/ZH&&&ƍ_&$$tXmذax'ANN v˚|PHHH޴O277}233wuuF,de˖^k }>/ƍqi33quu>|x[[ۍ7YIJ=߾^3700Nv;߇ ҒvKmذѣF8q|NCݻW@KKKӂһwvޝXSSCGO`%Ԝ>}zUU~AڵkWXѮʕ+d-8sSSS_MuwG__͚5=xwrr ٰy Tkc&`ӢnGP,E)JܢHRI骈B>E)TyL1fgΙ93999XPP088å N>QQQ! 0ff> %??Ֆbbbo޼ẓG/^ [N`',>`itt0K[[XUqG~4zT&?Nyys萗߿EEELLLw+&&ÇS؆G  0=4%,,LTTB-Zٳ0 \|YOOoXR ~@ /vܽ{w֭555}}};v066TmmQ455.@^2$%+׬Yc##Q}{{۷!D@^AN8smذR|U" /XWW 钉V\?߿3NcA;wL%{@^ill$/400tdbb۷ߵkXCODzeːȫbccdee;+--f6j{0W7lp֭s:~8@x |ÓI 899^:ΙccƷ200<~BS7p@^KTO]ύ7KDDDTUU׬Ycccsim\\\ff&y$$$֯_nݺsm߾>P 8^?&Ç̙CJJH 69sZ5,Ubff|__|@^-8XГ'OtttFս>4YÃ`JKK .888x]<&&FAAOII)**T`n߾ḹ>}rwwDs_ /,,looBa455xp b䢣)M-9sFBٳgU[^^ (8;;)))Z!!!/^qℂ RRR "=2ףh,{񄄄)˗,YBxxx=>ΥTUUh49|pkkkxx8y m!!!gϞ544Dы/`uuu4-..; h߽{̌z:giiQʁiii@$..͛>| dffOPV^^JzJ* O>رCZZx2xܹLIIIc..Aysrr""%%E^BZOII ̔˗/ IYYي+`IYYYBBmؠsM6QUkO8qƊ šuM{=@m: .?ʕ+6m:v{TT++Y3͛7/\0!!á达>>>)8XgccOXZ֋-lllqFook:ee` CCC---gϞݾ}>JhxseejFFFrr2TN[[[JJ]hX /;r䈸8F$;;Ebaaioo'=}GNN. Ιmceew^TTTzzzssWaa!ZXXzjٲe .,++۶m|N^2*wwwffl힞}}}EEE^,--#gggRgϦ<5s___AA-[~m=.,,ȰR{}y|hϟ'{/( c~~~-wW%%q511vI&eӧO#"))ya?Gqvv&y`p( $i;wϟcbbBOO5kdeea1aaaPSSLOOӧׯ_[n~MPPpbbb>|8S<NH ]RR[~~yhh(\BKrHHHAA(ŋK.QPXXhaatRss9s''ŋGGGPi>N5{Ͷmے#""+**޼y w%%%D .vPmݺu/_ݳg@سgϴ%uqyyyB7o BD*++.\8JMM͛7nݺUWWBTUUA^o.+++..?bcc $%% 8-!!dd9ӧO!4ak蚚 J?000?| UUU,{ΝW^]~_^^@ X[[8qb˖-EEEgϞ]nX+looGP,,,>|0&&N0 X8Di,c]N Ww`+hkksrrz1J oذa֭9992ZԩSc]?k֬ޞDØgV@deeyyyU~CDD4^^Qt`ll<Kǹs笭G^#''}adddYTTTTTTRRrҥNw{ͼy,,,DDD^~wEZZZdeeEDDgZC[FFfZ999A&yVVַoϟ!))I500JIIyА}tt4|pK?P?>>@~@ 2rުNVVv,&D,,,IKfffXXXDGG EGG[uC`` fZx @%7??f(++BNqqqׯdgg_nљ3gFƞ&Q'OZZZYZZ /"""P(K?yyy4-**ITSS++++//m:::ttt***4]LL333''5k>}Db)++iiiǏC#;8,bJJJW\oi+;;իWceegee555zjNNSRRD ߨ|߾}YYYO622طo_yyyMMMhh W-# M:''/_߿?77'vXѣٳgwwwHHHܻw z+A NPgyYOOOSSӦMV^Mb҃Eeffvwwlݺʒ#;HzpǏwwwzzhki㽽xqBBvo߾7v߫w3 PQ^R__IВ%KRRRHO/">^by"RPP ##3J}bI?YA^xAzl?K5 /!BGv߇/%^}}}lllݣ'%%͐ƽFGG\rXɓ߿pϟ@1_z5q8###ݬYXuhdzg&El…Y`y i=NĹ%M"n  USS$$$'((hjjaZX,W\\|FZѣ8_2KBBB]n]^^^^^82888ʊ==='"#GP6lD*'tL0QQQ hѢg(IVPPdիkZ[[_t CwRSSܜFGGIn ''gggg__ߨ3J:jKvԤN rrr.]J~Lvv6)cEEŢQzY``$333 O>P|C˧÷4uݭ[UTTرظ"39oܸϏ ;;MnnnPPлw DT%//޽{fffaaᐐ''In q0߾}+..VWWdyyyg.Hwww<ׇ]]]IU>>>===l毿jmm=ZGGӳ/''CS>o\xQDDQBBٳ(T²b Ҡ7o233333^z!^: FGssYfP(99h \2V)/u=yyy %""re:ƽΚ5 Aja,,,s7uppŋ?joofڵɓVsqqN4jC&Iׯ_HMM=y򤸸co|*J#mݺu֭%%%K444444F."!!B^B:604񓌍| R ߝ;wȫHL(,5jX})>MuuuJV\gjj@ubbΝ;?}f͚ b6gaa,߿ ۷o+++'I666jjj׮] "c&KTTb֭ˁqܹBK.9::_F3\]]###555%344LOOc522MHII~x?aXT3ɟ gʕ[޽v90-[ Aa۶mܹ3%% yEaaa;Ou%$$:ATT-lv) VZ!TVV:tGf 6 rܹUǏ_b799y#'=BBB666V۷ok׮Mddd _~rJoooє@;c/g$hѢoҡC/^%%%CMM۷oÌvF'%%9::`0ϟmܸy  ;j#66ׯ]:ꚓ{YYY///aaa??bbW:;;nݺ5)%0F******...7n`ee͞={<*1o޼yALW9n۶o^~]?˻k.i%{0j_EO+Wzzz:999::;ntE)p_@@`vvvphѢOfgg Ν;***&&&#a``000Є:s挡… ]C''mm8t&%%7&&& ?~b.R^^1gϞ[!bdddhho>/G %Z.cd={6y 77wKK˨ߝ'88KHHד qI__ѣG#ˉ3ן0 K.}xVN|%0ݻܹsÒCIIIzW3000ɩRRRZ~f^^|ʀymr助9i0F999yyyG߳gOvv7u֚5k6. $444 ۗcǎtNNoڵkcccGz(///333== `mmt%Z˻o>jh8O>Yfw)/^t]̀%A˗/&_||UN>};v,\PKKٙ‚%%%VGEEAl%߅ x./,,looB,`0QQQJJJ||| 111T_ C#_LzpmmmmAAASSӊOp8gkkKZ IIIX,VNN.::|p8nnao?l)XYYe˖ϟ?WTT,XÔ /1 rqqO:X[[988vM:s̥KÃdǟm3~~~eee&&&"<<}JK͔RUUE í%iiiٳh4z?^YYihxXX$Lm۶9sf```XyCCCzz5k DPѸ׸8CCÛ7o  4ۑKJJsqqPWUU%=^lYyy9B) 7)))zJJJ#?,##3VX;S"++G򶶶zzzΝpW:::qqqA/.\pyA 7mڄx|pppOOx}g(/5z뿐!?e[?ԣv8nǎIII\|YNNNVVV]]}ݺu7n 8^2!#Ix|[[[JJYsnn&qNN΢E#aaaioo'ͯ_[\iiSKdee\ &Ç &nٲ̌xd|@)vwwgff+,..+..ܱc$ޟ?+((زe˯gޅ===ᑙ;ʗ/~ƛ7oFEE"%%%__#GP(!HJ yՔ~aH[l066$44C^^w޼ynnnNNNuuu??AdޕX,v&Zjjˇ%%DFFFT2/3=/slڴiӦMӨ<<}Ѥ66600+L1>>QZZZQ\\zj ###`SSS!,ÇBhƣGǤ/]!m_ԏ͚5W\APrpqN8 UUUKJJ5=?Ǐ/^L,abbZfҥK555S%0;#//ܹ۷;wNTT ȵkDDD/++s;wn OT&%%$88/|/`F!NGM}…3gTUUqpp=z~ KMMw^FF##;GEEݽ{WQQXRQQ7]zQPP6jYPP|֐@Ξ=K8%:::99ñb TUU100̟?_EEe:΂=gϞ Җ-[feehѢ~QQ?c뮧Voo/y:r pv9A۫/_B Ќqqq//7oޔmݺxf:eeeE:::UTT())988{ѣߧHII5w}}l%<.AmZ۷rppppp={VNN.99>YZRPPC~۷o'>5]ݻwmmmIyyyfРlذc֬YGjjjؔttt%,EDDO.\ LEco~֭a_v߁htttco%n'OJYt{ܨj`ukjjH?SWW޽{UTT^x!""xYYJۤa| fҽϞ=BD3^~>9v:ݻ)//_RRvڑU/^`ff޸qK111(((PO_YXX߿qF J C,ٻwիW ;;;%i&-- A {NLLl*4ZQQk+w^bbbcc#''䵛6mRSSsqqp孭/_W8!!::{n߾755qqq]rRMMMaaaeee歷mppÇif8ЎѐjO: Ȇ  P4F:K,/_fޮcccC -ZTPP0$CtŊ)))l555++TQQ!6+VXvA~FttA__gϞYXX dddhjj"e˖_['$&&Na1\&666sQSS{I? ޽{jjju4###K-Mo|UMMŋ8uԦMWjʚb8`kk{mҥX?ӧO#'1#q/..:**j۶m>>>8oÆ ,x'''mlrrr"""!!!9Ҿ q ȶ0xyyiiiP(===MMMss{dTF۷o߾}kX,ǏV>c{͛7ߏOs+L2ADvnT &0gT7>`E,BeϿu_RIa܊[XH_Er,/_RUtd&qdb8Y/k?WU,[Zrp΃ds4㔟8l$+++[ZZgl|ddd݃O=|ի6)ʺsΝ;wv7h| V~ՓqM 8>>$/ݽY/٘.',eՍՍ7R%:b1e5k>H-?,`[gO\Fy KOWH^M.-}`ˉ&ثɥ[F\jdL*eݧ֎b.Ftuu!1T$---3n} Dh- cM40hQ?U] TJJ7Qo" M G⢙k_G%'''''spphkkGDD|JT׵TSYVVj D2 ?\|h%f-՞!t;$Z;8.dkk;%sKL/%%%ênܸzj QׇPD-qdV`\ljr*K~{I w IܜO_߷|oT?f"=Ιkkn qÎ1}5)${i33a=zBT넱_{Aڋ/'7˱^{'EU*ZS3ȹrfyeVZy]s;=(lEJc#?PY,FK<*dAPdjjjxe˖uww?~/!!APPCc^|'4jժ_ܼOx"~Tyu5+ϙEv@V^U]]`jjd_ ޿NFF틋yKy1r%LB"fj./gK{kgϥx_lĞW}$]N mcffhۡCZZZ^zEk׮ׯB 3ygx86dAL`}vLL̰ˈlmm---O< !B0xQu '[geOAL`JHHXjըWW]%Ky_6lh@CC7₂%%0y}9$Ν !$?*-- n@y 0yXlhhʀ@{@"##>}*##g A|S^i9DÓyԩ?233dggKHH@pY^WWWWWWŴKy %@^ Ay %̗/_  /.\ppp?xLLRTTׯ׭[',,b555޽KZ$))I]]EGG-))IKKd`444[ZZHU#_LzpmmmmAAASSӊOp8gkkKZ>փḹ$t`0)))Z!!!/^"P]]MLf }^aCCCܔ>?~JJJ?ʕ+8I|vZ ~~"aeee!7`0yyyRRRħmmm-jhh V ;B*`0999'Λ7T"--M\>b0Tyyo19ݟ6XU3 =}mmܹsa#`ډyضm۰¸tD'..͛L"33SII媪˖-#=vpp466VPPXb#H %>(++[b$WRRsR0y rwwgff˶oY\\WTTA&߿ۻ3##ҒXgw9;;Or544?WPPe˖_[>R001Rm˔9ׯ߿ڹs'隔-[?~311^vXWTT488cbn@@wee%䎇zxxΛ7CLy]gggQQQss3//ymMM͋/Ĥ!\`jQ8KZc^300pͻwƮ.,+##cnn~2Ǚ.CCC w200TWWoٲիW(*;;F-YBGz$ikk'/訪?{lrr2J.0ݻt5|jjj02o;w=z4%{L4啟/$$tڵꮮw]~]HH(??5CA>|{n777RR ŕ+WsK~3S||j۷o LJ @X !Gbaa0ZPPPPP /+fffXXXDGG EGG[0(**Z{66>Q@;|}} DYY5C899-[lƍ嵵7npww򊈈v=Ǎ!ٳgCt 6ŕO >~Gښ⋱xʳ -Ɖ',,,P(T__ݻwsk׮Zߟ8 ?555;;./L]߬DAA^ ''7lP@=JpRAAƍjjj$&&8qȨ BZYYqqqA%jAOO/&&Fb;B>[_qÇ5>>!篿:uTkk>|ޞI E P9*uɵk.]tKݻx}W瓒155@DEET7oI>>yyy(JMMڮKXXXOO… ݻaÆ_X'QQQ! @=2*djjJ>iY[[OD~Ͷmxxx=gggi\ ܌=N'f?qL%3 a!D m60.Z@^K /%s^Vy# /%Ky %`0K3//|w<0Ϝ9cmmMzѱhѢRzQQ` ? &..NCC_XX޾T5Ťo455xp b䢣WH\IIIZZZÖ}׮]BBBh4zܹnnnmmmS$L~3V\9NUjϤE666"""(SSS=9=yd۶m222LLLX, !!w ߝ }^aCCCX%%q.U[[t7oް#yfAV\YQQAGG` ooomkk~:jX;I% fAAA ~~~󏠠``` ڵkm޼̙3:::_޴iq=;}[;wnҥ aaa3—Q`` ,Y@UԤ}_vgN~(g2#6껄'?8?l$oNc}۷jw" `۶m  Tt=22A.\#vqp6d``@w9|%KP(ѣGǹ*`0nmm '/IKK#2$$ٳh4z俣ϟWVV&&%䂃hLNJnܸ'$$ݝ7w[nMyۆפ/ '&1̈)))EEEUWW[XX rر 3ɛ'۝;w"r &%qqq7o$33 edd^ӧ$&&Rg%%%ISA͛Gzɉ y i=%%%666SW/_$RFFfX~}X޽ _d4d;w 8a Ν("" *8?l$+//𐗗gcccddEq&o^݋ڸqc]F)'Vkeeeee%̜8qBr;p9sryrrre|ĈҶE}}eoo/m !tK~ gϞɱzo >oɱ>|8YOa}I||ԩS[~#~*?D~~icccYYYG5͊ԇ>iTvY ˌJeDD!Cr\.2d{DDRKIϗiHwOUWWt3gά^ɓ555JrԨQC/Quuv.Dq…TTTܩƎ=k, [rpp{nqիW__?o޼͛7:99[nܹ =%>}zDDԔ۵~֭[~ԩ{?~QFTTTHHHVVVcc˗9I!VZjժGGGBI%'Nr!!!&MZ`aPPJ/Ν;+++mll JZre6mZ\\\TTT>}~KTnݺ5<ѣG3,sAo߾BË/ !OюgΜB888zèٳgT*]| <EY៩飯M~***KjB !\ -cbbrrrrss?C@h^t~hss%KofRRכ޽{۷?^jvZݻw9rÆ =>c} <#t/}//g}s̱200vvv9996?k&9sӯ^S/gDG#۔899I ]fΜ9s̎:)))))I$##W]| K\%@. r K%\@.r K%\@.r K@Ϥ]knn8@B%cSYY @vTu]K\'ֽ]qQlƌqa Z[[%?蔎K@wA.r ܒd r ~Eee… #055@.,ZH__XqڵEmڴa@.M2LV?ť4##YP( OO[n?'KdzHKK7n޽{7oT*##>  … JL.;99%''Kh4^zIaaaqر;lmm ;wﶱ100ݱckYK&&&&>>lذaSNذa۷]6`@WI#GT*ULL̝;w4EqM0>lRUU"xg͚U^^^[[}ُ?\+...))n߾}~ajjMNNSqqq6?^N+ܫؗ_~&^={VwG!ĹstKmhҤI㩭8pIAAnayywܹseddŋU=rF#UO8Q+;vLh4}Wy~c\| xKB;;;L{...+**/^lee/LLL***ZGGGNNN!!!eeeUK,zJrȑ];7xCڞf̘>HvĈk֬B\reٲe1 ;6;;}.66P#""_TTQ3~+m8qbm'OJU@./++hxe>::ݻ^pC5kVvvQWWimm-U)Ǐk/ܸq#<<ͭkR T*Uxx|!!!MMM*bcc%Jr֭&&&SLі''' 4wޫWyHuz=hРޏ[ZZ !ƌs=[;eŊFFFϏ3g{Ŋ^^^FFF>>>:Kf\y]6o󬺺G͵cn#O^`_[y7dnܝ| x|tRsssIII``ŋsωG77zʕ+~s??????F ?u@.+]vY7 @%!<Č38Gc} K\z}!<%c7/$kg8u ⫽ endstream endobj 264 0 obj << /Length 2426 /Filter /FlateDecode >> stream xnF_!%2bXf,rH@Kۢ"qzZ(Jv@XUۗvϾ~n|UUL%&fYm*6ʣ8짹YyXw0-)寙/~(1Q gˤfl;|lI/b {BLx W8YѸE<ψd}V672<j!$ii79"oJdQ,IJZ=b*S„b-3 { B͆EٻWٔ 90]j _Z-yYXQYx"MDr VauTBpN$6 .wh;|pH/,QKsp "ت9 +ȭ=ˏ[ vU"XSgUiRA4J*zNDQ|q#;iDŽgAi]5b-Mgs^,8pYQ۳<*|KLkk"1 HB*I`HCB9!P١k\=IPaS|!s? ;>Z1!HXvJL9^~v 5PMTUD"ϸD=+׫V\$QYDQcGu@UW-bsj,5BD̞j#nc2c v-2c ~J I\LPK0 4$BzC "J8y斷90X/.$$i8X@@*7H|iƼlo\d_ #NGʒ!5sp -[rѩ<ї dPh1z-2=JqWkkh`?p!5fϒa˩qk SY餙ڶ%G#,.CAb*i*؁[^w7rpuajMjZ֩a؝>H5Hb-RunO H>ȖٔOэ'׽XS0I};kʨlHVrͿ0|=HKL)L:xm{ =xFUgЖdl19KŸyYE>DeP[r5ŤI7, ɱ&%g^7by9$V+EmeQ d}/A +~V蘟Yxbmx lG t7(ڀD<ۈxyWhfEJ;5,Xc/iB&]'.Is<Z^UD(;Mтsmˑpb2 4#L J猹%^)<fQmԆ~Fў[:[e&虫W,{2LY˶ZNO"J |%]Im] GL7WxϿ.&P\/0x`N0i򙛒0GwѦFn*2DM)ؖa‰(fa:vKi|V?4ҏ*E nzͿc;bdJ\M^IcNA,44ޅJdnA^S4q*Ҽ t϶M/rغ01Օ7nImp6v cDq2`a%iy y?;fuZ$`:Z߾._:&WLudϺLMMفfz܄i{혍~>^2ϸ.0/xMiGǖюLW\'W.ۤz;ash7 ȳ{31nj/-j.leZ+K8h$kvRg"\:ߍ0Ɵ<[!ts#˿\ٍ(Snp{ ="?3w>?^,J-ݧ#xmP5o?1^vڜX E&([gXk0xuF~+v⊦ߎz_Q^kCiO1b~sU0SyinajtYK"nV?##ŀ>=#ggG{ #) ,Drj,UBZ&uTUsX}yQo endstream endobj 269 0 obj << /Length 1370 /Filter /FlateDecode >> stream xڕWK6WVQ$譯@ =$9h-zmmS]b693gy8KIer]%֚:C3E,p{꘠eZҙJ>+҆(&mԓN>9*Y 6O ~4>%Yq:~B66d tH4L?a/|ԉ ϒs;Pj۠i~Y0ĖeYgL*Ib$ɽEQ*퇽͒7,莯CйdcChZ~BZ{_ɭ)fCa_w$I QA*kfៅ^g=;EBP2tt&&dGvE3.\HGn荼;N?{K&lǀ4HJGF8y}Ln2ĊvմџbK~g :EWHp҄P_';5(Wf乕 <v(y "8`[I4djyS#+;DV{A|:zP"cĭʎאGeמk8`"\W9W3cqza's1f΁es#|lrEэ#6͜EZF{e:Okm;lVWz5[1S)F(#M̛MwruWUkzN5)O(ɡ%@NâXF|a- J(ig4]_'( LU_LhuTxet~B@^ɱ#8-̋:k?n:(uCclyrY O=FK~/ lB,LSya|bhI}.⩖w+(+U̺oK[~7GVuS=C_Xu}ĆI`)C 71d2U0gc Jh6KTXfyjIxAF7*ST[SXŸJaai˾ ]s 7+0?e֝q8o2~=Ml Q疂Ɇ;.̛hIр A)Qc^{k c j!H?X"N}?jmx'AwLӘSGfc " / ƛр3?1a`jFS}$ux~WtC+IY d XIΌ endstream endobj 261 0 obj << /Type /XObject /Subtype /Image /Width 474 /Height 595 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 27108 /Filter/FlateDecode /DecodeParms<> >> stream xw\e'܈Rʼn{+njuUmmo[n@ąDk3~%$>lw]^|](B!v2O} pEh`ёL"SCurcEhOî|!ضP4 ջ8&P좼,cJzcP좼 ;;,$..֊2Z.!-:꼴㘅CEMKVQ5dhM1T'ʝMű'R^sq01EQ꼴uV;ˋl6Ki6|cR( h:=Ņ_㋥|})^NSaQEr(JV8t2Z9tǭS6vq' %fuy9)Hjx~٪ˊ$fx|J1`qxb 9A=QmVTSc (H(.F{1 Pu^ڿ1Z2+;{ۅfblRronŞwȮnfèщvv+2jJhXj^Eǰ:mXU(}Pߝ&MU/Zt٬GZZڋA3)tZxxyQ->+{v1AϬX,q,%漸HBHAR=ō'EҾ18q:(7{{?] t=nJHL߭5]Q^N[085*wibn%EߨxU}i/b)|2q%.T_ޭdiP1p?TB7/OτoҲYʕLÞ+(6Pc7(X ήy:&VB-"\65^سx.2%2E;7AҲٙ9c:7-|d GCHWˎ?TS2n$ ~#犹]Ց+\5[?gK {+q =Hb+_7TH)gs>{(4DpiDX_Y֎FVNOUJ0df~֛W2~U*y̬hi5c6 ?[>UĦHfi,8#bAڡ8R\UUrR8a-oea /FFքؔiF)΄/ٜ粧MJJ@($,Ǵߏzuke8rqs13}۪O|w^mo$WXoI%7X? X'saxֺ]gGli_Wa}*^m'+d^_dimW'6%=MQTQ"Hzdau,m+?2X(i&wDG-b|"5ޠy;=qbE3Fujۡ,.e[t6yϟ2̡XTbՁU"R%g/:C؜8בLt196 )%cAaeEvvVk{9wl;h8We ˑ3WĽ.hcem|+ qNFOnQz'u5|}5),߮ 5k͔5UҘL-w-y7K#8 +BNĘ۩ϣeyYܺ_p*ٶ˶+dTҤ#+x<U\_#wupF!;tiSgKBW~1is!_=fs uf iE[Sb !-[X䥾glE#\! Vor+%6lijeBH_=1m$$fF\&qiwVzgP~0wBtv![虶E8]SST5"l.e"XYr.ҩy\.!~-AAX;X;8% <&wbB!Ό|%#ю`fNyBTMb֖?\}.: q);6ޱyjkˮ6+Ba-&;fQޯă{NIuШi+[_{9}`Ø)<ϭ'z+Kz-uMJMz(oMޕ4[t]X.ܰEW4j.΁"i`{ijPҪw\І~M8V_f mGiok|([i8@,3G$Yuޠvvkۢy3&/_璎e[ϋ s6R2ڐ zk"y7o?ѽUvFb"195,K7򄴡9+[rq9[!g`jZGjSzu-?az"}͕,+=.6Px_^I9|r۶(?keʾ{ujԥQ,O+YZ鉶C49ztn3\dЬsjq~laaHA : _F&Z;Z;|pYNzNIE|BWch!lgڂk(zOF|L^ZuK.:Y&/-1ՓxY^HN(t%r_Fr39<W4XuJ֫c ͨ|J}3/ Rba q}K}iW[BtLyi~z}A//!vL+}Bi }C/H R 0MzLuV=IA[eL 6apu"Hó -Z2E2b|@߈+gr4 EɲhZ5JPp"}\ +4/UyYQh 6q|ilKLEjrz&V=CĢM[W+bsyBPlR*;O Vpllq5PgE<q}=sVCVQgjm=CR!@qELff!|]f9꼴  HW^`im#!ģ߮8|B:Pq)u?Eedd|8 !@}tRYcVM+ 3j/\sٳg 8w*8Uo@u۰U_Qm|}}gϞVX_jqe BCC#""~ŋgfffffN>}ѢE]v6l}͋ZޣG1ɯSS_x2#=xŋj:={vttPX׹/_YfȑOru37o~ɓYC\.>'+Szԩ3fL4k׮xhy8''GOObaa!H7%7111">ERYn1!,&x嚚~5|"7ؑlVBB_ܼ V&4mor)& x_gwyvРA>>>xhsӧŨ˗/amb)iiLfnn.cff8Ǎwض|_VئsϞ%ss"1)#ZHזf?X=n8hyҲeroɓ':f.@occ#51H?Om8ˋ$T}4MP W(2ŲWYJfQ*(ɋP qU,*Ւ }ggg3S<<B86zm+ifT*J%_ZP(DBD"ML|P(l 7m#@7/˕( Rdy{ĉ.9luo+Lni&JeqqXP)ދ΄))~mB. dĤ7>DO[~&Eq\'GٔSNd&r\W8n1Mӄf ~? by,D/77cR,-mN 0"\|[5O.F蝒bު:H !g p/D;.q9\uoWn .}v6;+K$dIZfg禤 |Bih(Ӂ% iCH ! 722-9?3f9վNCfq iĀv1T҄ h EQ|ccӂ|B+,KTx\Ɋ(bYxh[ۀ?~>nI&yy/sxBQ.Ůgl+wGR`LB!V(G^4.,y%M۷jn!C)yyy999<>/\>:nΊ"X(V* BP(U(J D%󨸸GV(1qK_TZ:.+44t ~Wr3$bPhֱ\.gZEJ%3ʍ(Yt~Hܒq̴IHII4MX,q\^XccW^?)oR/4 x\ܹ877;&abK8J]ŻZ4p8//_@4#/fA-o? j::%T$k/q,}SP sx~N"5X811Q/Ru3maE1WJ%O0br܅L7 !$55񸅅2BHqq1wurgx|!_>u|GQzRJy.)Ia% ߐs8۷/^xAwU( A2RmFQQ֮]x<y<iWd Żvtw}s}r{3g31>>Y__7?iiryqP=BH``3ß٬Y3]]]}}}PpfqfôǏ?dȐ]Q 4|>x}yӧO֮][K,qssR(|>_GGGWW7IlW]t8;xb+*z:мѣG `aaaaa1p'Ok;ZSNUƸ{掎f A1w>;w\˟믿1=u~xٳgW\a c??۷o_x]$D"ww/^zի 6mڸq۷opo|++)S\~=88G0Zڻwʕ+Ug:::_~QQz0T2ulbblٲ+VT4ŋ{ejjکSÇ3w1ydd׸'N{ܹO̟?/?|֭[!F TѣGe~LLLLMMurrÍ裏+ߪly@Zنe_GVlݺuݺu饦oٲ_6lwppسgOn߾K!4Mٳ~۽{7sŋZ000P}3wE[U-/Wf:QW⌌ RK<}\nn[~~?0mڴnUUl嫲@h8`;t:th```~~~~~~``СCb3O>}֬YVTT4K177}v4iR]U?.9ZzuXXL&ϿqƄ Tώ5￟>}:s43}7>NG.'$$;vO>ݺuS}"|>8OWePM@ۡo߻J$*Ҟ:ujϞ=.wwSRR/_(۴ihѢ9s0U-w͚54Mpw\v bWM}MݻT*thѢA1Ox[nRTccck_Q@ :99M2ݽTP[UU4Oe@m\ti%'0j>5p֭YfRqq\/wtٳ7|3yZzn:;yyyI$zn \~:oh@mMu481@SQ-E@cqޖj8Kw 81cHe$]w+o=q6Ԗ:vVm@q c@ q 8zc@3ZLjlc8600طoT*utt$11yK.7nԺuΝL4X*g̘1cƌKkExxxxxxTj@q c1 А8jMȐH$=e(h0Gm7:33{tV4K.!]:+ K ~ᇪ^Jqr 65PŁ P c1 8@q c1 8@q c1 8@q c1 8@q c@ q 81*T[rѣGl==6mڨ6ٳGܣ~$**GgϞMKKS*O߹s-[T2svv͛܌xݚmɊ+^#ޱo3ʠiZxʕ4ooo6]^H++rg[`AE f>sjd;򵗚Xqk.ckkkR,\Ç8z%ݻw W>c~ȅcǎ-U®]߾};3}ƍݺudTu%^vֿ7ldѣG !evϩC!?!9--duܹ*飚sرUY{%;;[WWW?K.&.N2`0?۷lqLLL|~dddHH'KJ>4M3C ###33S zlէ8*JիK.uwwѩbZnMӪO\?cHvZP %?VF- eq8J4X.vΜ9k;vlVVVmK.g]Zݯ_*~l8V(..J'N,TkKTG#BB-<_%|piQӷl2f̘sԩEՕ\xԨQgϞ}Rξ{Ujvdg޿՛%m߾=//䳥N詨(ֈV=f۷U:$Ɏ9RW^֭[7o\lEm۶e/_͛ y`K˜ZBTZ8w\U>3޼ySX5XJnE7B+mn:Tq 4Mի3נz| 91ݻ*t5C1ˆ#Ə_>8Togg0fggm۶Yti3899ys8SS^zAcו6Vqkٲ%Ţ(!$$ӲeK.kkk?T4vS [bE*9fРAJBȜ9sٖ,_jAT@IDfx<ÇEƪ>x{{#Y %Er\S3m4G.O4Iuϟ8q"wѵkr6Yc_[nU=6b۷iKFGG?Tfƍb:ݫYZ8 @4kcǎ?3oСZzEΝ;KP:uDwjO>i;7Wbou 81c@ q 81c@ q 81c@ q 81 8PCItE&%%d2T @CYYY 5@hh+!##M6ƹwСC/\8]vMOOd߼ys @9rD#q c1 8+=ڹsgLL JcƑ9~={Ϝ9S.,8hPYYY}qqq)))3gDeq phtuu?x<!DWWB}q @nݚcǎ|}rrrP"@ԻOnܸ\.SΞbq P/.\b [[rovQPPBmٲ%>>~ҥжm['''OV8/EEEw޲e S٭h?={\8/G TlC}ɳgP1@Խoڴsrq?~E1@۶m[~2ĉO8Am˙ʑu֐*斜ٳ`u P7n𰳳9rٳgQ:@ԙ{YZ5tK.z83k׮3gE~yyy( ѣGǏ]t~aPF@-[rJDR4h?jcں|,XP_www@q P+2l>>>eVE]tIJJJIIA1q Ps7on۶mmz~lv^_b?~m۶A ~͛rQ}y&J cbyjN:%$$8۷oo(KcٮAAA(,48(NTD~zĉo֬Y]-GoFmc|p=z{. եIW .MP盚VVAԭ[\PdhctJ@mIWWe˖(248>r' 6,''iUC.ʺp¶mΟ?/c诀&Ǔ&M 066pB^^z UǾ WW`JBzܺuw-** {*?v 6t֭G!i1!ݻzJLLtss-^i֭[gee^Bдbhh陓= 8|@@Z+(ť| @f1;|pXm3w}5\]]PvhrqXnFS@E ԻwY3ZP-xӧOx]v CCSc'v%wҥ7*bp% ys7z&O]U-~E5]\\ñ 1Y}9ظWt}BhCSGݻΝ(k8.((v޽6>ƎcBѪU+]]]6jvرƇD8x𠗗W#n34xdEffK]w_~biOh8>z(hyx!!!VVV|yAAB(((x١CBBBpիڵk޼y#nÇ;@ӄ__iӦhB X,@`cc3u'N恦ãqAGG6::9vرg;wLy qӤP(Ο??f̘Fgg{a6DZ)!0ӥR)qtmKKK+++uc -c흐 h&LPM_5bu *ׯ :uj3_i;t:lIǎB@:H$AAA=zH$bX"fԨQsD">nacAvdoochBVp:u @Cr޽{V1_,ch*huzq AƊbsssu01 uVϞ=pryrr2 I ѣzn[׮]q Mݻwǀ8 vک}GM8&4֭EQj:7_HHnX,n޼yLL  A]\]]ܹ=cf ",,E7>BǏ5kfhhq8-ڵkW5vڥ~ Ǡq=w @6 W8&_8$=zԹsgT7771 AkEEEjJ(bн{4bS|q ׳gϛ7obǍw7n^1h\;jw=222??ǠUbbb4<C$9::atYܷok׮a-5bqIwPqܥK_~%##w=k>yo(SW͓ ._|̘13gtwwg4]PPpq4h"BYƍuΝ=wܱcǎ;fee5cƌ?E_OnܸhV*8V?cffq[>`+W xĈ#F(.. =s̺u֯_߯_3g;V m +biPc5 駟ߨhp k׮5kp8OOf͚-X ""c;h۶-zv"}]tiׯ/**֭۶mۺuo999iYdd !C NkRtȐ!'/bcc/^|ҥׯw8ykÇ#:Yȑ# !<cƌf%gݻwPPQqCIII,YfLOOWMΝ;Ϙ1Ȩ*u4ԩnP(۷ŋ===7(q'$Fy1;(rFDZc1߿{}8'OPe'< BS#q\[999|'ܺukM!>>>ءP_q\PP}vB !::}hcǞ?թRv;Ubffx1c`u\/biӾ{TÃ:)S9rSݔiА"##g̘c噙{ZiY ѣGuH$ 8y$,@p@xCא!Ν;gVVsN/!!bjj*CJKKKOO׸t;v(Jnq1;hРsB!nnn2!Xtuu500믿ն~e˖b;wiӆBM*C >~FWH$333SRR̙L izذa2ԡpmVQҤIbbb=z=8PSNNNZ2y<޼ymۆ=8+VX[[s8 OffׯJbܹ(R@WxBBԩ|]iU{xxiq0WZ*%%ETnPqt^%Kv܉j`Z+|󍉉ND58n߾DZU h/2ؽ{ С/aZ/<\p#SUZZZZZZVԫ1bDjjjHHqX[[_rb5Ȋ۷Bƍ>\&ajkOմFgXs碁8Vk'l޼Y"Z8BCCv_YΝ;o*i+(( XZZ 8ٳ+WĮEk c8jYfoڴ '>!!!Mϛ7jqdee}۷ L3EQ7nܨM޽;!ڵkϜ9?g) ӧO7 rvv644Ǒ8]nذ!668}tBO=m'!_-ԦMzꅽMlӘ1gΜ={H@ub+f@-cP5eʔk׮|gϞ%l޼Y*&23Tj/((GMzzzcƌ9x mũzu^BCVV֕+Wp(Gf͚5k֬+V@WHWW7333??___TFw~ǧn qFqݽ{ɉߔ15w裏pT 8j(DfL5z Ou5۴iS-ZX,VS =jk@kIO>dɒhfJ\\ܺu!gFnݺeL:w@Wh„ 3fxEǎ)-[O(/ w[r<,, q̰tttėL#+ݻ[n:::BK.v@텅nݺi 4::hN]-3f̘15uƍ}*cǎ]dIzz!(C 0ȈHÇ3#Bhժ.mٲرc>/%E4hP] YYYzjzzBHMMpѣ[٣GS:uӧyyyJ2///..ӦMѣGVVF+,, ٳ'JQɓ=: c„ 7nܰL/yK#8^JHHh ;՜'OQ 1!￉s[Y666+Ø1c! 2i\=a< fQ\ȑ#1Bj1mu:::>+!׹ׇN:\\\֯_}.\0n8ԡ"Ǐo,YRu07˔%IPPЁFmkk+X,H$5jԁܹ#H5TAAי./"66+:.vr劓.|R j`_}5 1@o\\\>cF4Z"|||"""Pݻ'O޼y|ou P=QQQӧO?~Q\.wРA@0믿⺏:1bĈsΡc9r䈻?|,ްanܸ|% >Ν;၂XreBTԖBILLJJJjѢP((y*22_T.]t<[#G믿FR w/r9Thiiidd|7o/_:884kɩV5S*,>" xŋ,Xmnn kkkss;w?vګW+W"հWu Zx޼ywiݺ5 q,VG>}48-4|>rQ 1 ql޼޽{ǎ0aM斘 q ۶mgΜD`٣F:uJAp*y4Me1_qQKKKTC7nڵXı&),,LOOdJe MӦM;wn޽qh}zzz&&&O)XcX[[oܸ6m47ݶmL&[jMrGdTC# 6߿fjĉǏGǠJ9s֬Ycggjh~Ž|@ڹs'!d(Fp8cǎ=z(J8nݺ={Z`GAǠ.]:o޼mۢZgϞYYY(4˗߿W_ZgNz!q D&-\pǎ^^^...F)Ǡ1njoo?dBiҥK(4CRRO?eB̚5?@Ǡ⋹sؠg„ nzJ8uw֭ V'NDq NP,Zh͸~w\R A}޽`(k߾ñcP 1uرzK.ݶmn85z'vz,..x"Jp&-22ԩS?F)VZ~Chiz޼y}D"A5;w@ٻw/EQ3gD)ϟkǠ.RSSWZsNE4i/R A-,_|ڴi:uB)_||} .\u '))O?=rwaM] OIX"@)Sa-JeJUw[ю#u>.u-ЀK)+-7o*$A?|͹{דso++B3cƌ:4A.ᇟ|ɨQpuuDLJJ7TZUUU^^^RRR^^&-d4hزeKrr޽{ܹcggbECCJϞ=߿e2ϨQ&N8qDsss4#tm۶<|^F ]vڵrbmmmkk}NSS۷˸ġC1Y9zMmll).+۽!zԨQ}ٕ+Wnݺ4iҤR4 wС%K8;;5; 8pŊƍ?~ܹs18UV]t ,))VVV>>>#BΜ9SPP[lݾ}{HHűJȈӧI>}#""=RzU*w^z6lذ~iرDYRXX̙3鹹UmmmFFƶmܲѿ`bjs]vۣY+ Ç+**$JH$G+W|_MMMNNΪU}]OOϛ7ofdd\t Y ׷kذa 7yt|BȩSfffnnnnnnAAAgΜٺusZ[[KJJJKKݻWZZRG|w} } MKK:ujllɓ'njkkfy⸶Æ o@7?x3 7<<S#=dҥ###&oT;88<}D}t̠NW⬬SN}'NLOO rYXXlݺ>7oޡClfQ׃ !O}zHHȘ1czmB%ɪ*++߿_RRR\\LQTpp/_>x`r_xŋXСo|@#Ǐw aaauuu?/^ HRJ%e2D"Q*|>sppf^XVVC@V(555ϟ?D&&&fff<ĄB:.|!XXX۷ojiip8bkkKlffFwsss |.p8P( 5kH$z#!|>s(B3v[89~]ǩTO~0^MccWZZ绶„ >"(:w\ZZE*feemڴIzK.ݼyvQ SL(j'NP-88yw^___qcc#B ۷o{9s(ׯԩS"""x<Ν;>L?v؀1cPeggC?5eʔիW߽{(TqFkkk@}_ѣ)߿}~\u뜜>rȸ77>HAAA...׮](%88>(Zr ͛wիWO9r$<<|ĈLQ&LߦMF9k֬c2^xqʕ7BCC.]i+Vt钑2?m,$hWS0:a*++vwUO>Uڪ*ToWQ&"_>ydW>d6'JX\WWw=FL3\^__c*++jQ#Ҿ}VTTғN>hjjjjj|ϙ566lBF)//*fWUU=x@"ٙ~'ND"ijjz葧'<}6§OF]v9XǨWVRRԍV]]ieeeZWLVw(8Ѓf1~ 5NN9!&O| Ҍqzz@ /yGGG.+˫-[VYY_?b,--o_n߾fNE&X.:}o."brlrf꯱^ȔbP- _fcftN8)e nz2f.W}sOi4 8qh^FKQiǷHPx{{ƍӟrrr VׯOHH ̜9S{N^)I{ҹBnݗ?˖-ׯ_k566vm}Z[[ !ǎ4i@ PJ*r\6RJ%9(:T*U*3b]\.Mc˗/;88 >\T0ljEq8Dbaa3CVT655q8-:^xR\E]]iV'OԄxb%FPr8:L%X,677gXtҮ6Rϟ1d2SS+W̝;W.r+++zrRhq$I[[S!d2͛5vAR)?$J%hѢu9::N!]Oo2bĈsspvٳg .:t X;vX°Ǣ°( xٲeC)yz<C[O5mk F8~=;v̙3%%%R/"""::u. u}5m4cЄBBB?j:L(sqqIJJjll=o<NNN)_נ(qjj*eGgÞ={rlժUt]R#GT*aе,$hWS0:6 >>>6myfssBx'|BٴixJBQQQIYn&&Օ،;ٳګ);v|{|5B RpA EQT ۻwnݮ\./++[jUR*AAA}cȑJR^A4(tk5Vhw}={u?:{Q_Xwz4:K333 !yU #66v"&&&666Fڷov g͚󭬬Z[[,Y"LMM-ZQWWWBȽ{?/\@ٿ?Ç ! j@]K`CC!0KΝ;G Lw(((0## E'&&/-PHdTTTBu\K z}HׯמQ_O?dG_Bȉ'?.\H UOٳgkW;չ;t%x{{3Kf̘A9p% L275w܌ D Guu5!ޞYHq.>feelٲaÆjf[[[SSSVV!䫯(%ɲel 0 ;;[*655}w;v,fܹs缼.\L{.!Ӯv4ֹ;@Azm̒k׮B>}:b333 ѣGlaƍ,?ow333.;d qp:@ WlBH[[DRBl+t<++ׯ+۷GEE 6ёQS7zgbbBI_eR>}ŋO?RRRp'NWWWd2Qȑ~`ggG&L0;;;ӣ㬬Ç>}4_֠Kvۭswhkkl6{ڵ/5Ry3gBm2qlHϧ !F-~V;NNN[l!Bϟ_]]=jԨǏ2qKєJ%!ԴW71+++""Jһw;S{q?mڴlKKKlmm !ӦMcٮ^Z"DGG{{{lC&&&oΝ; !=B :tȑ:uϏ?0K庬Ѕp87nB曨(___.Jsrrb;@O:uΝ;MljjzYX8!D^T'OClu;i1<8x𠩩ի;zB51w׷o_8pz LvڵAB> ] 2ݻu.g„ \.WBu{%xxxOӦM#DGG6}tBܹs-$((㵵 888GF7ı^㸹csX.h<5bB ][1kk[nQ:u㲲2+++FM BYt)#s>k,68~ժP(?1p@;/x<ŽbggW^^KyWùpBbbqvvNJJefE;]K_w} BȊ+ҜLLL\]]-Zt֭O(rG333[[ۨ zFe3:W_ow*008155o:::Ι3...:9bggGwu}INN9!&O|E6lؐxׯOHH ̜9pWJ( 8@q c1 8@q c1 8@q c1 zS]VڰaGc 6$$$tMףA^uY FqNNqb:ㆆ`q c1 )!|.Qkh*g endstream endobj 275 0 obj << /Length 2088 /Filter /FlateDecode >> stream xY[D~﯈4SoxpﳷSG e˯{Yv{̘I@펿e^wn:~WV/aNSg2`3ESt" MmMud ,-f,,b 齣"oOj2-_;t-Oے:W}JR-~1 IF^xJ}l{%{pFǍwOJy.Y)&N0JsO4!"C$dfVlm6̈́8Yf<;73icЭbx f|e/R[ZyXy-e}=}<t^4@XA3| `D>rUM?q>1qH|wRw=l q*qjFU[^W!h!@yc LhpaI2m]$(ky@4:Qג@CctڼMO3\)9[+/j@aTY}_:}r WQڌ#ʅT9jAÐU;RcTmc(TdPʣM\9xY膑z̾ o'ZtÍ׎ރ89V5 Q\9Kő(Fqw"} J.݈5|"]p㝨 вoT@Rc5ԕI4tl.B#9^\aC>q%*J8EVY8rKATB'^f$w ],H%֦m$zڗ㞻Z90zH\7&Xm56@X+ڧI͖P$U*zK }*`c!jU7%[6:ҏRh1$UEj˜f|y#"Cxa2^Xl*ԼmS[VL+P7@ j_|h6H=IP)Hb4ac\h#rSyTfEY"$raYGMN qe GyiEO/(խTdIAKW|>L4DTbWy'vCƆkv;#;Y'Y׆el07I~&Ӱ7l5c1(=S_Fz$!غώDknv, ,c۾[91^wɘ[N-K|‡Wb1=;JAޗ+h9v`epXjaj'Sq{…*O *ZVyw\ՋβWJ'.;Ǟ=N9֞P6$4ʄEZKvj*߽6Y?*BGlVw n]6vG{dՇVۆ8pUwQ'xEe2ռoxR2E=.RcBf A:I-ok{K?YqMa$j%>qЩ&h2lgt L󺄩QRo8 Z%"Q\tbnA}1/]"=W G_<IOV9y 2@3{Ӿ~7 # endstream endobj 280 0 obj << /Length 1598 /Filter /FlateDecode >> stream xXKo7W=Ps -ڴ!iQ94=(JlYv]73!lRE{*䐜7+g}w!ųWAΔszΔlgupBJ;[nfV빪z r#[ʡNdLPdEHcu>MoLԖR5%[J2dJf?-^L*_+$Tc&7Q#5l!1~AclSغ0NmM¤56EV$t|` ge}lwDpW ?&c:'>=Mit&op}R.Rzdi_El\DLTi}w*-ij{6f]-]s'UN7b&Z2cS r3VKj$=$xVp 2pBFB?΍9``Tl0M Os[ k*iq5k P=;eXGB9k51I=\0!#֬&TtX1$+>+uʋOG!S{5xuW+\7tuvĎMrJatkJW\c nІ{r턓kb#@XsU/v0 endstream endobj 277 0 obj << /Type /XObject /Subtype /Image /Width 452 /Height 273 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 22455 /Filter/FlateDecode /DecodeParms<> >> stream xyXg}p"r7WEZ@kJ9~Ƙ0Zy||ٙw}g; @ =ɹmcMwF@ }6OS\ьB@ H/xWeq hmwZ@z[`™h%:;[D!P}_MbIL~?/WDЊqpi }ZZϜ)Jՙ͌cH!Kd\)))R2\sϾj[?ޚNb : U0XDYo)HAԯeڄg\-H$52-)&4*)Jj ]ݜloB5֡pHMC۽?n<-l$(L,E#LbU}؛h=2C;Gyz,҂P2KtlϏUuH,>A(8@m‚,wjLfՎLƭ_飖ȼ[s}picg@\yJނ3U卒Maq;WBB5`&1@JNW*ik}əϛ(Cg_SC=.MKȴke]Z=`6SN^\ ļnkN7 .ﵕ;G)C8yeD2@aXV̖"'lx{2*Mc^+C]{$(f˧K%:fCwɘ)z|N)96V~߆Pt)ﱰ3".^ZS*^Qy*RvW;c'g7"P(Ǡ+9ŵǓWUm!C{!OR8EOLII)}V!fFsΜ<ɡ2kP`vs^qgH}>auQ*VvPx"F qk1:lF|UGљ9um K+Mg%RXzCi6 _5lNsse$`0Í^a4PYEDo1|5;Ȑ3Ȑ3b@#:):J9X,#2 -7#K:eoKv '7 ]^,g%&Q{D*e`Yh2@l(SӥC`z]0o3c]WV\KfvuQV٠;C+cl, &uM,%흕 |Gm9F/sZZΖ-I dJ&X\Z֣ٷYC-yݨ:3t"y@;/:Y} CNUkWJ&<.lhyTh?”hj3eOQymc OK2L0S_AxϑdD&T6{Gz2fhg OR.FCG|}+8 C#>^áݎ Ld9#͝x) WpF {aa( #+@WCI%WKq1gS%x0şxu6V/n} Cuŵ¶5u3R[޼/M4~ÇNyLͭ ;"2DR!?h]~zDkLZ'}j="ҹӄM:p]մf1~^ʂd:ΩWk04:rf_i)\JA?ѹ x\Qkۋ½|C 3~ YKCίm>wVҺ&]Q4|)^QvQzD2al@ā趚fQ^N:\:i՗!^LP! s\YgUY[9$:R!.ltYM1Ӗ <XA{M7kM&Zqv)9S-vq]HN@aėVvt4 BRՅ6=KM~p((biK$7Vd:WV˅~6C( %yŲ]ueķMPbUp dZ 6= 01h{fcti0XvUEmM@c[4ҡ/ tu)TD%DFKk_4 q`E盐e4l->k%Zbi $*%Rj_dܼi2(J hR^usM\S9aNT|5vsi㡣G"Q|V]sjf}{WoKSD%z3 %&" J LtU1 u`+q;B?SNeJr рQDD"moh}aȺB^V.ЙM(:NfEc \ksoΧͰc~c"jhAHaG|&BFӄsMmCF_}VRPZ9td[b"'R6 Ga 7 _*~SrLlt-3xxbs&!JuXM*E$VOp4rT-oz`$$]"X$[*Av]؁ M̍@ITgkYI뚠$;4kJ \ayؑvbT%3F$e?0 LsSѢѺ sItp̌_"؊fy)ZskCO,C$,4p{] 5sIHFUv櫖vܡܫ6Ffh5W~^s=Zե7(nIjk=V^~f]n3X,f5}zlh׭'eRԁx1ȕz|wi fw[XȖ 81^8<^ź0Ɉ*s0|@`Ab$]RN[nن%_n\G;*j׷XJBeCԍ&8%):F{=ضbWm <:ϔ6ZC~)PH,μ2wDb uvq") @c2Nݮkof/Õ-2tv;d6]{WػݽQJiz(M_ (u֙CsۮliTg}A^HPo,:dISSF}bwG5 #/tbML4sŧá?o& [t*ie_ƶT&OyD̆WY|N5:wH+3c}=O8G7cdE5^{]H$yO?^ctD"u635~T9H8׭&8$jA9-+c;vLe\͇KT.8 ap/awtJV^v+f)gaMee*Ɋ̭?)@SQ]w셽-8\/C6}dWƝ 1{gC `0嫜 IFG&TXv4Ȟ3&)*oN‰k$3ezP]ݺ1XE4CVHfM5k gΔm3IP߼ cfR/i6%ٲz d*S`FИzR QG; D$*W_\'P ]"x/5$3(Da:[0gJf .m$2TA"EaT`7!3uT*hTEW9Zj 6FC Ďz"UV'3u)l.S@Pzv$ Cb(t,UևDgdJَd4 ͫP*D @acT*!96;+ٙq Bpr6I˗zq1N&_|" 7*ྞi}CD pbG#I)t"r%BBhl b`y?gDs0pPP<@:RDvQ8\t CN +*]QttGK=C0@̖Hck]~SEaMQ[Ӥ/_T|~=\S[}7FYO?e K1xH֪"7PPP@ei꒼ ۖp E.L(̷]{I_^ |_+K2|A D1St Ig5Is Swyns_:2nmjksh:F:C9ƖN-6W՗?)hmE(BsYdλTwZDf_&K(Lۀ 830u)l>Inl+>J 8z–zD'R(,]2SHwN ^ @eQ+Ѿ?bDքHeUїr04@ 7M@ ډL?Fl;Z\ T*- y:H \G:yMi[%))㦃- y)y VȉBkB HbJe )hL!:SyTWW{{{WWWCg @ … mmmЙB HYYY,X~8S3w\]5]- ˬ^ϯ^ZM4@ Ϛ5 6$wٶm۶m4߷[l4#{Ն@}˙xUVurʕ jmmuO81n8}}}ӧ榧O6pܹ>cƌvvvG7ٳgc|>)**JeĉǏ744w3JjkKA3}w477>}ZY''}S;vشiSQQQNNWXXغuT3ޏ?,'N H+Wz'ݻ|A5880tЫW7sվsnݺ߾enn`kRlllmV__ޞ;_7|) [[[/]?ZZZ.^hjj/]tժUnReV2ϟdɒѣGwZ 3]t dZr% 4(<cƌFr*((_JFzzzzz… e)~RL"Kx|ZZp 's骬ѣG+A/K?Cy͛7o<)}{KJYKA1pn@3@ L!:S@g @ ЙB H_CqiTﲮ~F7lYݙ ^.gq@g T@ n_8f @ Z:S@3@ L_ɓHל9s@g=b%D"QaaŋN< m @3Ոinn.--5jԱcǼ5O===y<@ӛ5kVJJoBt79sLl٣o.V"ٳŅd33 dddh rFeQCiJ(jlllٲn5o)7TгgϺ{yyz<?qDl@@Ν;7lPQQQQQcǎe˖K *+섥1 z-6000%%eϞ=---ϟwrrZ|fɓ'O4)..NQb=5P(LMM-))/BiȿWUc[?J{ @,׿N]]]qqƍNmZ[[7o,JO555YYY%&&tT k"bTouqqIOOOKKsuuդz{7jRV!`t[,M@muVî8vva/ T"T*e01NR_o(BzHH`ׯmA'KK,EZ;="//nر555=: w'A!ׯ_3fLWg333=<<=<xPV@n%3?U_vȑ/_ӕ/^8b􀀀ӧOkXo(@ lܸ… ﬏+j:3gFEEmݺU>Qy 蚚[HLq8BoKÐaҥ}]{{B?Xx~*o P;tЊ+|O.[L$ɧTTTpwЮ555 S)))G*EO۷#F('"STtSN=zso޼Ϝ9sԨQcƌIIIiiiiiiIII3f̸q<==U 4hŋWX]{HlDD3gZZZۯ\*bX %{0o޼x𠠠GVUU蠠pB"Zg*>}򗔕 V;wnʔ):::( 3g>|xĈT*J9~SQ$ >hTeb^gjj(pqq|7LҔ\zיJҒk׼tttxk״ uGw|mcK"B '~GFF\'%%JR,7GFMFFFggJO (//m@+q@g @ ЙB D4115|@3+! /^( բ&QF;vرc&Mꪬ[ E 888|ƍS 1D"9|p\\ܣGGg9R3--njhhp8#G;vL,ӦM hJ*dP522O/_|VVرc~!`Ȑ!~~~s̑iӦEGG+[FWj,#p= ?ޘjZAC죉2HO@gLeeehhg}}}YPXQQqʕ5kָm߾$$$ӧ[npEEE/^\vl͛7߿Fڵk֬Y@X\XX~_~+D"/_.֬Y#z~z7lpl_5kVOKSN}g݊֘=VGC!LRs^^^nn4,E"LLL>3fL8ɓ}"111fϱ_d2Kqpp_w)/[XX޽APq޽k֬Ν;wʕ4ƍ9rq㒓e-[M6fٖoNLLLXXT*ݸq&T1hy6_"T*e01N(rnsr7ntuVyR˗/R~+nZfC.pՇxUVi9ѣG>~ Hw'AaM6SKvvvٶm۶xbOOM6ʟruuVX,.(( 6s^^@ Bܹ榜&یǧE[u111?~LL-#C t=466M !'޿?===;; :ty<AVb˗dD_}'|`^*nhhPHܾ}>@ r"dcǏ_nW#J1Aw]=GEC:J$aXWW'YqS eԩk֬9tPNNe˰S,Ka)<~GHJJr~~~=ꌳX,Q@ ##lk Qi . >\GG;>|xZZZS}+ CO )֝]^~СC{Z@ ZXX`NNNW^R_Fyzzy|n{m{{+W̜9S!ʕ+ϟ??eʔ7'&&ʶE&L1*Ozt:>p8Ag~s5*k֬D)nE~'PPj׮]ʢL{k lٲMl秜Aݻwv嬚ҥKEEEQ_|(I9NKKS+g*HD"TGGGiiillLj#4Yty''' ׯ/\;;~ &L2%%%Q(޾}oÆ *9sFV1bĴi.^zElTW/2/X 44w58qbL&SaaҤIG75kBCC?^]]-kjjBCC5_|T obl2L& GG͛7˿mHNN>rի={F&Ν+˶n:466bo@uZkٳg]vlܸQŋ߀Rfɒ%'N]uƍΝn:lݨJ{vk̷:#o|WW۷]b9;; >(d;AoG6{Z$UTT'E?rd222rʕ%%%JR,7GZd٩ғ˭`A Wǖ-[ݻBsC Lձpw6G@ }}@3@ L!&[ҧ{02@ ͇@ L!:SMgzIkE;[H$¾FuIhkF4NsssiiQ;>>} A=2`h4ss9s$''+Tڵk b^jdd /Vlcc#{քT@"ٳŅd33 dddmt/%EQcce˖577w򝠡2{L ={{0 j2`^paɁ_|ryAttyϝ;7**JOOnE?;yI&i"*000%%eϞ=---ϟwrrZ|j,E((cO/@3J,RD"aqӭ[222;>En?gΜm0QQQ?zB!˖-|JxKKC>}>L_twb01]>d CusݻoǭWWW7vXGu[DGGG֩nKp9Sٓцzknn|ݻfCȑ#1116m:vu-Zh"M}͝;}ݺu@OX߿{ L5w5nջh644;ͮ%lŋ?ccъ*/V,?~| bzQӦM+.. BQٳF4iREE&(ZZZfff߿M.N@AId![%J311YbE``&kkklJϮ󋊊8PYY_VTyIII...ءP3fƖY[[kb^k/ tE/i/j2)k" DdK.mjj}X-66Vi(aƍ.\x3gFEEmݺU>N!gMM -G8N&! ZbC%OKKˆ 䣧\ ]jUlךz.%%EɲeD"|JEEoӧ(zmpĈqtrr3|n!T9&ud 4hŋWX|ȑ#Ç5jԜ9sq/R6vڋ/vbXl6WS0""̙3---W\|e2o޼x𠠠GVUU蠠pBdbMsss"VAlǹsvܩ0qr^lv@"۷pBoMO9jtUGGǥKl>jժkתO?nmmM"?n@z6)"h~P㓒R[[ [Kݺ:U[[+;ih4JU QCq wL5'--{P [Y>>>=9996l|bvv.?IUZKŅׯ _z'n 2224Rw"Bz_ϖ~WBmۦm۶`Noؽ{zȻv'OܟVE8H ֡6V;^?OH#?d޼yُ=?ݛ;w|ϻw'e[jժU jmmw/܆A oL5 XҞ䋗/]={t#8U^^NPsX$NOuA>CGG罻|||Ԍsυ ())u֮]3l߾=""bԩ[[ۃb*mٲi˖-˗{]CÔ}\=D;)ҥKwNLLTISյO<)^ <z;wv$ۖ˾3w\Yw~>JZUUղelllx<566509r#))OhǙ^t飏>_5jƭŋ ;To־v.sΝ[ny{{+H$pB:~鲲ڊF􌈈ؽ{|vt:hәjIE+6T+ǤenK!rʏ>h8zw޿ׯ_777'H g1SLAQ޽{ءSZZB4GGGMg'>+kQy67qXhDazɌ3Oeff K. \rEޟl߾=))) ϙ3g׬YzjX\SSf5g}‚v4(˼IX-6lظq֭[SILkk|ׯ={gbFGG'$$92!!!&&UY=D]z; dQxT%=}! @ޑ|ȕ+W*++JyՊ*&Lv!)@g @ ЙB :S@-p8"F Kad @ @ ЙB t7ɓ'}T @3UX HTXXxE//'OB[C L5uKKKGu1ooo) 3gT.؈}Q!۴iTJ6mL;%Hd2 |ӦMb[0===y<@ӛ5kEezz!j,RvPg5(/[[ 5iM݃U镕Ϟ=swwRT;g5ybcc'O,J-Z$޽{wqppO{l t ,++۳gϐ!Cx|AAAjj333 D۷o睝hvܹ 6DGG{'NĤ F7C/SWFA,?~x_|ѣGrHƎ/85꺺:ioש+..޸qԩy<v뫑PQQaiiYYY.⒞ꪐm޽fRw^5:PԦ&5޽{ظ[Z[[m޼Y2=5j,vxC=R FuiҚH{֭[{[:i`-G 2=Z}Y>dɒǏ̐WWW7vX@MMͣG,--eg.\O?=x`Ȑ!n݊/\GG'##cҤI\!C={֭V?7|KvHHȻUo7n ;\v3= qD"Ѱ;6o޼fdEEEE)|7,~ %To߾s纻[.::@M\}}n~1cBB,Ím /Zs TrRSS?~| g0_|/**y,ȝ)iӦ(zQFM4BH$\` ժ^5R&S[;hwG6eii7p8sVGD",]C!&&&+V Tvqquuu]\\~e˖kע(+xy*:cƌز2kkkL&̚5+,,[l(Q׿d2!XL%-555 7p8)C5{ӧXO<'N:U>?駟233oܸk!7n\zFyYf[}|M,S; t̙3xU.\(KSkjj |n!?2p ^ :thŊuuuG(55^a.%%Ea@AofҤI!!!8\nٲe"H>B>jt]?UsQ}6v8b8:99>~L%H$:>ikРA/^bvblOO]={vjpvv>sLKKK{{+W|||,YHZMw\CCC{{͛7}||l~,v"͋ :zhUUX, -@sdbYrÇHlWSW^utt\t)V Xv~tZmڴヒ077g0ӧOހosDTޭϧ~qkkkdeeu77w 32pj_[XK)"***dNS @sA)))>>>ø4);ӦM h42rkkkUU WY=UyWFFF|s*џԃ@Ed X`I|RV/HIdү>T5Uxݻ`h>nU~LOO/_漡U'y;.Ճ@4Q.]ڽ{wbbzO "}RXIEuj`GHJJ漡U OWю3tc_͸x"aG mmk슋S/FyzzFDD޽6PiU&۔Q=tMg'XRbU4\|:eEݻ[H(X)--M!OZZ#T)L5gTy67qXhDa<>>>gΜE䭺f???H4n8S__믿B E=zE85 2odehb̞=ٳU]]]\\\F*U⿬d;RwR%UIO_0@{iz~ )%s[% 28܈٠m#@& t60h}!SAt@"PtRR&Pt}qJ|?{ν99G9 0E97P[ѧk[;)k׮ŅTa> LS@ L-0a 0)`&i]]݄vTYY1SYY9͙ |wbb}YW׎YgR"L׬Y>O+++ޮ뗯߸t\ L4OM&dgϞ{nBBeѬWMVfRL݋@ 3MOnOX 9uTdd主xK,_x1Yyba&L !,秺wlpCþ˗2~2GQV~aEh4+:y+\]]_|łf}BB ?#pY*faaatu2tSr9:.Kpe4Ns- O)LMM길vP8{"e2Ybb"!~? y^EcyfNO:HQ5*eKo0z[މ-^^^6}Wرc6m]\\JJJBBB^{5믿f٫l694os !uuu2󎓔B8O4ڮIJVkM088XZZ˙?k*g1;Y`R=q… g mL8'L_{GC}XYo}KÇ#Ҿsr)h4 "99yh쓔k09ھ\jS]ic?-mذz}xxxffT*? -[E[n ްalٲm۶amիKKKJҥKJeYYիS4oő)G?Y#<3 :,ob̛ryhh(˭ k[;) 8)a S)[f8@ La 0n5>$$Μ9c墢GyZ-Fh^WjR)0'4(ӼyS֭+//gtz@ᘚT"e6Ӈ^CQTwwwFFFrr&<SBH\\\aa!<DC2]\xF IOT2WIx/rnn+<9Ӓz6; ߧƸcc]4Gcޗ9C,ڱcV\PXXh^TXXO) ӧO[^^^~~~Gň:f4<|lsݟ#?\B8BMcco|6徾---7o6fgg~~~---nnnф_~%55 o@9zzz|M4`Ô;v[NV9HQ5*eKo0z["y̕+WB[PH8p +++00)ڻw/YYYYYY^z饼<4.\4瞦̓Y(((M5cq´.77qBܾFπں[ݯmmm믿noo7Uhh7߭o:\t:]mmmRRRUUUllD7̓ى=UUU+1>! MbfafGv}WTTzsssWZjsA&QORBȝ;;?1X3ԽB]mlld>>> ˖-/^(]F/XԩOyN SIJ\4O#m۷oOMMzhSSD"abD"QTLі-[袔DrŬ{D"QEE;--M**JFCQT___QQT*MKKC&9SwӺ;{ >oMEQgǽ7:LK !QQQj^HJJJNNfbqooΝ;Oݛ~EbD BP*B ž}v~zժUG `Oi g}MMLa 8O"L&M] Dbtw̆T\p>!uo/$taz `TG5 endstream endobj 285 0 obj << /Length 1900 /Filter /FlateDecode >> stream xYKFWPP(3*ql'r C@- wߧ_3 A֩9I9B#5B?^|#"Mhv7*tde6JFq9~>O'9ڝ&~񌀋 hc<0G a2M:.cdZ820Zx1Oiy Dp&Ǝ<=|b}hGStj(QEO!{`]>/0;\R˒T@y9Ȕe+V%B'&4nE5DZOJ'|+UӃqHQ<*J|}XeU-X`HLiA4HPMdX=bM+-+FxM<ԙuQfitw/ҴdP; 1GCO*Up{ ;A~h>ފlG)~ǹUz^2;MW Nu//W=(x ܦhm "[\TU+FK+^'ұ=OUN x#p:GwmDk-##osy`+BgzwdZ$G~GG u/=|?;@>0SP; *2(5㄰J%M>x"VT+;`U(|$U_p4ETh֝ed5l~ޡd)'0tvDGޔ-}c@\o]لQYA=`ܩ#0{VtZV!Lj5\G-٬q)7tح%sDlѹ*c$zz8 e.p[#ay$:=N iďz$rXs\}?lNl(}bJ.>ۢC?\EmFJk{I^`nͧ_$US=/.{bqPU/lx>T$ 9̈;6OeZW2HYa td4 ]]="j/6N1˝u;Jޱ<_*}sua> stream xXK6FHT=hv=NrhzZV6,99C~ 7:Nބ}]8YiȜY*0}ZOٵ//bm`p$ApТ$H5!ځN> bM9%Yu8chZ"r02c[Nn7OA p ϥF솂78mԔ!RrZ0 "9>8 RV qOfE=NELQK]G%La`I bm0Tq}2al ~I+7a ᤊ4`kq;> stream xYKo7 бh$! 07Z4HrHk&Hz ߏc;Yy3 HE~(spTKiu$#A],щ$jJX+ƥƋ!Woo࿊c1cNY+bؚ &9@h"jM٥`BL<'LׂH5RTI.Qxx1m2Eh1d<0ZԦ@\K*ł)83LHCbG6#lJ[%5+U"gSD8(T` G88D 2 $!Cb؅5o{~."ؼ8 r$J0IbrI D$ x $v \v(p4〙|R Uw 60*i̔S J̕2]HL#Φ vU!1U*?\:G:|teΕieXТd5A-®9)%Mb龑6f;imɳ)]a@;#r,%jPIq*^VNGg듿>ԞBIlV KV> q!b݌}|(ndЀ6r.IQU0Z'.X9&M-%ֽޚV$0Sܚwm6خ136ڬTA~ {Y 1 6s67 U,_sysY6%D LEG9Lc}s8ÖLo%lq.,6k1]vQ׵So-9^ж>4H@ho iIl]D }Srq"Gލ:~ئ\H.s9/!agdL}r4*{6K?]Z#۴"uL^X84aM(}h>Jiݻv2P*|W ݨ&"҆22_ִL>K_hb endstream endobj 294 0 obj << /Length 719 /Filter /FlateDecode >> stream xWMo@WXkgJTJ* 8"qB_~kc; $#ۻ;ogfgެ17!6.R9VO)Ό\!KWYBtdhܶ9%y ٶv̫ѤA>[_wA[vN21+lHxH$[_3# 'ّ,H%&M;(;xPЛj-BHpc;*{{Gܒ&y`/qq&`@L/⧇ZǿQ6̻=upp.a4B̉ lRu 1> stream xڕWݏF`6a0 5(UCl: pqβacgZ[ơw",!8\kbaGfQ`;oSD%@ (ORY@ htAωU&Pd YBQ̯IWJu]pG_d@UtΪuZi3d[25IP=m i D|`̻A 0|"p!(v(;nh{q_+Gnz}KHMd)7ҩ2^RLS^=~z]$PB .ϹpN\S4ꝱwOl4mHxi g?a 14e+c0n)Eljh]^.\!}vdFg9~ɧ)y! M);;ۂ쒝Ҹ80+)i:Ws%V^r־R',*ULLe>P<{>&ċJ~!~kJ5=R"PiXw֤B̲g^`yӆ? H⪤3Sb֗cCUIwN3@ҞL?dp;0/~fW"I@iJd;am=dm:f_=t'ǃF D:4د. -ڮ|y/cDPޒ` +`x?evKS57|Ȋeͫ qKvgJJ!K:[~{;wVJyR%*+1 hT67)>2PhNҽjSE{y>2{%-˜eә-y f[jjpz DYu&&dqV)N VG_ַBvVUXS?tj'G[Wp@r%#QCh ڼOJgV55ex`Vu( ~=l]QRo5N¬S y*&6ݰ B75ՋVf(pmi>3Ym!?d!r|K?Wyw>a endstream endobj 303 0 obj << /Length 2105 /Filter /FlateDecode >> stream xڵˎ60ZEђ@ 4Ezh.ΩAkk~;9]/lQpΌz~~oT-hLZef4\ehIxbL0>no1p,(5./ex193aDrp q^&rsEZS>!|4~s )8W-ˎh5'Ew3={%oY'=襶tp{xA7\Jxn"w Qr,ry5Ez{oN1=Եy9k)klIּ,pٚi?{f 9<㋨qKMc≴GaTrjW :ۑ^{Lkq!^Ӳrupw0:m4IUl1 ԇ r\ooLL:7|\RC﬑QkжB*޿1KDA2z== bGS?f/xi(J \b%2m/ʴ,{ae`ia_\%lvh]1طo x^BxYzWi\e0C! IT1MףWS~64y; cqyPyx`)k>;C'v\1ĉ#pVKm|Jޫ =i$|IBL.r])*Hrg̯39>>BZ89[6ݑZ"㦩Tᆙ6UZΊ۱=jzݠ  ^X= b/lZ6eS4).+<0$\e>e,~*:0΀@JahJ[I`SG tsQ^-p'p*q]ڒ]ӻgzGK5I\!\OgFyS=3"¼0rq6[fZC\>wJ9.P( .d\ CzM3+-T9sO/% ކ$r!SY:- 7T;X7iȋ9xx`6CIlwL.*)"y'؏rgZµ Vq}u-su?1_+e?iFe@,5 vk4>5zAZ[Fi˖=A%HȳZ"hXXBu %ef.g9qHPݐHu(o1ȆvWC' h9;}4#;%V<>j |7t}EcS].0%Ml\~FM-A_u/ *V‚P[Q*j"U1K,A\(2oņE16Cpt#iIgi:YJ3:#BQ~xl;tVt:AL%*ȚXj1#=! BUw,5 Xζ/ endstream endobj 307 0 obj << /Length 777 /Filter /FlateDecode >> stream xWKo@+,W]yHJ!UFQLKҊ}zC}xggogK=VUGqЉ{v X8ᨅiEzKC2>p̖tDI{fpuBڂ- |v~;f̧AMrTw!P&-c8g0fk '`1~[o׌d2ɰ&0}ԃ"S}(=z)*ps\@XXzo7eW"0Zr`-c5F\i< c9`\,5N6wǗ=6)JI?M`T߀qPo4!c="L|Hퟸ.v'-i>YQtP?i8#!2("E%o@;rD0C+(rs;֒#FL2c1?qSXVlT37>/'3}ړ2R2VFT,7xʺ|!/?]3vQ`y缂(UX-y4WRZ]%M\B)릅,,4jrIj˫3P5Df~C*7EGG5Dv2e1spVN"E92nE`x؟(?(ӘD)2|_JDqu?q$Ͼ굑]G $ݵCdĕ$j endstream endobj 311 0 obj << /Length 954 /Filter /FlateDecode >> stream xX[o0~@%Z$M.eCh)M}|66MLc|;>;'$ BA'Gau^w]%s% %ҒRu 켥CtRRӏ|ؼ_0)_L3%=׋ڏm/%1PrV?2{|Մ?JCؐؐþK3`<"X3pݧT8r>P;7xƪ@Uf",qt#U+>˖L[65Ƨya s[< 8"Odq|Gf3%sm1@z^ ef}-BiC9BSu1xE/zqB,?A%k1\eҘRy &jNٜ(>IFg E~R\CNtJAe_}!b/&U ~)c쑈%fc'*-ěr0$$ٯC}i-Z3*j>CZجR,)3lݿ_SFZp$׫yYhm3wn^H^S&&n필5*0zcfT:dE wũY)/=:ܫ- dsUIu)aL'V'qx|kml,f47U3GP]TV :d+!1`E#jqwߙ]p-םkD[-9n˺:٦TrVXրߓ|ۃzJa^}2"۪S *&ttV:CupsO9 UB>Vw endstream endobj 317 0 obj << /Length 1173 /Filter /FlateDecode >> stream xXM6 ϯpk%Yv {8Lę,(ʖǛLCBd"I|3[xӛ7B,SJzӹ rũbGt}2d=*X5>JaiI1;zami`}W~T9 V [5~>X~'ɼώxz%zӒ~E+'#`y&lV=lɨŸNkCUc8,G5$ϊYy+˷'!d=x[gOg$E U+2Sto*_g-٩Ou'kX RJϸ9zvwǍh-1gcE>;aV0va"}rw)yLX%F~D;FZ2dЏr:vCE[;*eIҜ?Ş@fC#/t;++v<ߑ!"L(вTb @ G bezbcy;&/ibbOOC&nDa8ySvڗ)⪵DsOC '_$ɔEIbemkX\uY3G!L2^ݷ/PrurO)Pkj]`Mɽ_8_8;H:V>F 9zp ݻ\4 Nf g,)8 ǰ\3\,%wlhie0$y<{bWpmENmO{KE;47xGᢡԄ3mT%ܟa:>|r0ݸ\P=XV8d|甏W|  O~^j?*DV~O9,J?zڑ$gyǧ#r.ЦvԄ.Vbz*4&z΅97%&2+ UBd8InB /sI~zkR )Q+1~ޘˋHFmB8oFϡר4'i9> stream xePMO0 Wvи!8NH[+n(<>u aGa.!"{MfcH wyҳr-fJv!0>>" eͺ]cqzkphzfsB~j|4VpĨo_ʣk_∎:9V Yu_u XAYZT'ѹ/Y endstream endobj 314 0 obj << /Type /XObject /Subtype /Image /Width 621 /Height 334 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 35221 /Filter/FlateDecode /DecodeParms<> >> stream xg\YgHHB JQ(AA,*uPTZx,ka,*( T+(*(6BKH p=½sɜ2 b #A 2b]p|\5q[fvw[|,4ALj_@k( @GBT_- ڢYT?q)Бh mQRPP C]i8 tDBY fjlOqW HhP|JmxTh +'l ߠepGQtZ;E, T*5!1c5cj[otM0> E?(:!{Y\>]Der"RvY)LUC \x !i Wct4t(־FGmIPEOQuowѱꮙy(ix$i6^)ү/\uP(FBbk:P%O2u"6Tm5TŠSG%5yt&Gz;rru4zyb7/?ӣHm#k/4E䵩Gt5EuPE*s]4Vg<@ : ܀on`\=vO!cizx2xXxg؋((S&.Ŋ'ps4q&rOҨ[v|:2?kbowGcߕ/ҚQ^w҇jETU%ߩ5\liˀSU[׳(tC/ׯWw 9/htXoLߪB5*z ٍ@P idKQM̽M b7$֦F|kߘ9"Ӷ'&K6 |&@u)JaP}~FU)ROӴ53LE -@ٌ H}Roj[ nF6:9hڸoİx]HF)d>|70VBj1y*MAE?m~TKk~X`˂꺮ZA}5oj~X!FW(t2(OWIu[l]QuzVo^cYSSmccZyj}7Ku}@'E_ Hjze7yRS ~=˃)2)z:ZQҧFtOߣw7J~w@$@&tn|᷄ 'rv  &6KSOQ0ʭ`]U%qT> -4UzsonJebтKtJ 4:e12XXfsCmsosdR0$T:_ף* _]t*iƺ_N "7wshU{y]?Jt(JiQ RkCce[ԦҸD AQ-g?:M׳8Β?Tcj (|CǫjS}pw&\A _E Mb&"R HtT:Jg /TϏY/XQipyEL B%<͙ š3_U[tZ8pj6~`]b; /麈F @{bqY-zii}|rKj%t&mo} 8%TQN=H$҆ @9g+}㳇!>!QAʋs#5?T|˒-SgcBT%ȍГ̫|6i`\\ȩgޢ֥ӈ=3gt~Ƣ֬"noR z 2DfWOAezZ `Y (WQs2uT 7,XOFRQ*UQ? tx53j>UqaEͻPjZU>~N E&R &j7{H|$Y7aI(5~x]6eR"jBP`18|^TQX2IX)i,!ߨF7D"XOˋM|6 .=>G5mƒkT5ALf05hjj,M݆rQL^&WFTړbkt3J%L D*75(슢:+ őOW4 ̙\Q#{[T1:0et ,͢FPjj>SCJW5ԩk5 bYT" Nwn|:Cgr] 0Թ uF7]y<ELi`)#`iiN';Y:VEP>\6Nj0Z( A:"tu ,tEthxG: u F#h=4A&fZRQw  m }8菶st@TL6 !J+++@//0? G(@@f?K[[`X[[oٲtss۱cx (_bqddM'M]WWp˗6l7 ŋ{{ܹ3ftޝFYXX9rȑ#p߾}{왚 ~ҥK̙CL;wҥK;P0`áRXd2y<ޔ)Sq1 ssC뉉߿:1bDNNΥK p8Qs||IՓJR(seN;G7o\ZZzAߨ͛7wXmܸqΝܼyݻ={?`Ǐߴiӱcjkk?~D?//_ZXX ><88x>|(..ڵ ovrrT*}?0sLbsff&2q[vb{g<RKNNҥKNJJʴiP߿?gckkk_@`hhX[[ H~7JJJZvmVV2==zSwiFhiit6667o?|w|ee]RRR;,8EDGGȑ#[`ATTT qppI?|P}uqq\\\>|HX Ab;O>522'fq8j8 ȝ;w\H$zu6zH4s\qBXZZFGG9s^[[+wƍSRRjjj^zvرc]fgg^ʍ euqb1 <*GYfmܸԴO>3glll<p[nD̅ ߼yڵkuuuMMMw?>Q>==}p|iqtٲe :u*ٳ---{t^f̘<}t6=}PR>qDȭߺuttt455ϟ?iҤ7O<9qDڝϿ^##^ [wWaaWF-]4,,LUV-]ɉ'555555 rرv'H쬥bLMM̙s%ł]-@tRTLJJw}߼ysݺuFQ4##㧟~sΎ;d6j ˖-+..޶m[^T/҂_8kEeX5554b8 @iii׮]+Rcǎ4hА!C.\0~ֽ%ϑ#G q+z^paGh1Kz@~ %</,,~H$X)&&fG[[o}!11ql6i|>qSIE) 1x<}}}??v ''' 7jԨ5kjjN<ڿ^-,,=>fXt:NG;eʔ?}SGGf0 66V*((,N۷֭[7oݻGihh,Z .];w+޽{wɭ[&$$( Kw;wȑ#'N899ۿ~:331<<3!lٲ~o盛;6888<<իWyyy]v]x1.yM6={V>*kwU(@{ȑyyyve 5u pŗė^dVVV2LtXr>>/_NII  m@gn̟?ӦM BpÆ k)߷o߇RTK.mjj"cׯ_oeeph4͛7[=s d~"^g0,SD^D9Bqtt\lى'n޼uVlNWa 9oF}ZP:rիCCCo޼  /_v _ Ah_`~ Q8 G9PR./:aϞ=k׮-//W?7… Ĕ> /]]E|8|}S'L;f̘Q[[|F~l{{{AbqTTT\\\G⢭ PSRR ^޽---l68QA{AAΝ;gdddkkfddgfgg"ҭ[7{{{///777]]]pQ&Lc8p~{չs爉G~fÇ\.n5>oO4))i֭Ν+..nlllll,..>w֭[B!xQE,Yrzj„ q(FEE/ɿp;{Ǐ?~|ټsɓ'ԬN<L@vJJJ3b+ED xyyunHT۷)|̤)t-qUV:?t12===={ᡡr=< k*v%Iddd޽Y,˵ۺukCCVի͎;, 7(2L,v` ]u&/K⫦Hb~\FOO[nnnݺ׹Q>?gΜ={tR4 ?\.W,˴gAvڵzjAѪƎRXXXTT4jԨWTT(ӳqwޅo 7ovZZT*)jժ9s̛7 !)^tiXX6߁k]]]&bwŊΝ۷o_YYYIIɁΟ?*Hh4رcA\\\bbƍh?8p`ĉt:x0LUL^WaaaΝ۵kWYYYyyCCCj{M_!{s@MܖjK_ȓ2m4tԬTx;,MM͏5AW̩")-[\xvZ@+H-[f Evjjի/]uJJ?1 ߿ S+J322°O:<" 7ܮ{~o߾XLZv-/IJ T\\СCnj/k - yBSn*dW^SN:.tj?neeneeuWSS |822R"NNN_lll H$555`}}=KPR=&''^411ۃ ϟ?&>---?4rH*> srr999*_bMMMyfff644466fff,X2=;wN4Ia􊎎>2L==I&ݼy*nWV!;u5k֬]v͚5SfFmu[6mZ=|h;;tАWWW "JSRR&LЀ=XQ8AV]]mkk *pN0GU6lXPPVk.]rsst=jjj V6][[+odc۶mCEQ4===(((<ā zl6@ ղC <榩9ӧ+2$r7mܧO`UxQ555e"iݰԾ}(jժ-[;N OLL\x@&ɓuuuǏOR[t;IYr_"迊Ž (E|Θ1")) D|0y}Mq8wbbbӁ O155ׯq_~EEEDQFQD$%yeAy;v''X͛7֏;vsYZZ*ԝ5k|8p >rۢIʒJOH6ѷo_ ׯp84(%!(]lϞ=_xg%cccN5fggX+g!J###T$544>u[l]DB6Nطo_DDDbbBTTTܽ{wܸq- 600heʒb ljj}%KA666.\3ge``p5$ac놄566֭[3gv]YYYUUo߾'O.Z.Y$,,,%%>}U'NLMM uuu7npww6lѣU_%o]ӧgdd`r|||ܭ[ڵ+99YfM)SGhq&OV[[Ϙ1#((Un')Ky\ 3ҺuFR[ly򥑑cc#FqT*577_x=<<͛7R]#T*MHHظqcnnnnBBBΝ=mvE|ɓ'!!!RUdAAAXXXZZZ]]u@@q{LK ۶m>rppXhl2 vm bll{D"7LJKK pq @{…;vdff(jggpB.n'/K+UVVt@ WGa(b TOda#^ ӃweD"ř3g+#CQraDlIʋd(o.~pRo__UNrm%I~\m~@[s#.Ƒyfd$ǬU Yٳ2IFɅI*bA(/FE$ԇD9׍EGٻw/,܅8 @ " |=dee>/ip@ЩQ2ZqfAQL M<{lʕW\J[nU!x55JdݻwGGG(jff6c |!KKK,ŲgΜٶm[NN1b?lllbY111&&&AAA-jqJ33/\__J+7oތ9@5Ç /޽Ν;B˗/wssîq]h_>|0v!C?|ԨQ 0;~x (;` Qegz"k׮xrٲek֬iսC[jkk߻wv\*~o߾4yY[[;99aUJiiiaaa-%Kܚ@*{C\sXXڵkt:ׯ T\\eJ_a>}:**,KӉI(?m՗.]bXx}_(@'m+HNN&FPM^Ç'n'sFws%7D^ŋM!/\JYrT*G<>J֯_`0ZLf]]B A@l*l}1LU@:1}]ev6Tܫh___b?733v<33g3yYCCC[rrrU)bRiQQ… }|| DY{sI&);LWXb}#!##iȑ<9;;9so(3l6pB!y?חBCC՝\.)bpiWW׸8b`YV*CEEݻwǍ'1Z`g`'j"/T*ÊŮgR̩^ڷo_DDDbbB)U]]]CC Fc[df@T+hgyާ?B}zFF*'++SEnĉSSSBa]]ݍ7݇ 6zhUʒ۝:uիWBaSSӽ{|}}gΜ\֭[wڕ,I_}˱jJ6m`7%n:T䔔?s?.9m۶m۶Acccoo`l) !g^vY,âE:m;gΜ7޺uK*ZXXL>}ѢEx%׼j*H$DKKK[*`Ejkksb IjET*In:WWW\_S.]}_tΝ;5je0QQQDcݻgϞ_~E\W'00PVuE"bH$b16n#depU7DR`[d$,R"wֵH}-Z$WL Çwtt,**JOOohhXf|H&Ƥ.\pʕ/_vW^EFF;wNF 11122СC;wY$-%)թYzԩSeNzCŧӈ#22Ac*1drC$e ŮL$"f"TE2֏9BA) yyyX¢}ѢEnnnؿ~:&@ ~ ͛7oTN#?~}ၭS0q^|;,ƍ3g400`{!tp82益wڕ >x]lAnmmml"+++[%=s挓ҥ/RR$vI'NsNUf/ 8Ǜ 8ǻâpmwxb۷gffBN?3Lgg5k8886,<<t^NKKW$DDD8::(z֭={c$v'Mҭ[+VoݺUfɓǏ?o޼Fr$111֭:t(鑑N¶e Uu&K~|޽)S(nG ܹS^!]/^888aqttG_kEKnWk$gE'O|C@U?.%>IU644d2zzz&My&%ڹsI,K/fdd4559x}a8ɓ>fN ?utt什/^500 fCx< 77#Gl޼ܢݚPӣG`<+00pϞ=ʖՐ%]~Muuu#""BBBՊ}J|n+TEXfbo2#ǎ[re||AYfLMMGkׯ_QQE4`X[[>|8!!Iyyyd02؛!غVr(zyy^ \r8je"%Uglȁ7(2jԨ8c766_)dgg۷/"""11Faw7N&Mf1;;HYd`K3uuu @jjj%v[T'kEKnWk~Uh سgϙ3gbK/577+WRi~~#L ??{#77)~{{{bl"&p̙X,>3yܜB444FFF$mщڵkӧO700`{H$m^tzCC筃X,~䉇ussn''On.]L<%0ӧO{yyu֍`XYYmڴI$e^1s7 @hfP 2>Sٳg/^5jԸqi4Q?FeeKaaaQQѨQƏ_QQ MHHػwoIIIyy) F 駟JKK}}},XPUU%S70EUogVZ(Gmt~3f̻wcbb7l؀-ungb?W]\\󋊊\]]ǏN111Vn9s`&{zz޺u:>>>###$$sMM80q/90i> t:NӱvZ@H$˖-Xf322¶J_۷oii)FݿV*fddN>uyՖ]`0jkk˰kb}  *..V]OĿsôD~KJ޽+))QC;K= OO+8յ]`'\X,O|LNN޾};(ʴiӖ,YzX) Y(˖- RAxx[?aÆ/_{X,H^>\~=L&NX,wUTTԽ{0l]@ ~׮]vvvҥKYYن =f===l"s qeĈ\==ٳgu;2NWf4??t_}( `JCCÜd999+V̟?_p$;wnƍQQQ}Ξ5k~э v9i$,###9ҷoߜYfihhxyyGEEaØXCƍ5kքرX+).];w޽{]]]{---OOOos>vjV+WQsdtt*`zbccbo}wfG`0)bXMMMrFwww|JcGNII uuu/^իN| .Jq/\H$IIIT*/N?zUVV4-11X!CtadggH$266wfE,cRiUU!o|#G>}[+j|D~K`0L^9;obbR\\E(dhbfB²aaaUUUիUUUVzׯߴinDDDHHB$00pϞ=jjjpBvv3SAQtСh[@SN:::[jvv6"^kkkSS?:s按 .455e2t:][[͛7**#rooo555:`0W]Q-(œ=z ŋmmm ȓY!'Aوv6~8 qI*cN8r9SllcMRSS߿/\r12 XӔBf܏G=O[@cǎ\2>>,JׅN/^x޽Xصk… 3f%%%y477{7@2kۉc9>|pBB|5kVN8 _#ć2_=ezqqqDCcƌQ#H$v.~Li'iTkhh Vk*B;;7oV_zDd߾}666 qX/SL0,#####KOO_~áhĆ㨫co`<}ܷo߇ʜ5ێۉ.{q(Qh+׮]^ÒgΜٽ{weeeUUվ}N|+6r޷oߨ(xK߾};uT>H$ѣGkjjraÆ={}W~;IIIcƌvrttܾ}{SS?}\a02m4|} 5k6e˖lmmmUgRSSS{/؇A,STIcW| :0Dr1U 7h_ݹsWKqQDQv5qUBJU%lXbK񬏺v"o{5|;Lر?8]DEa@^#GK\&o\*UmE!f}ԅ*{H}jQ>ԩ#Fc{g_|`߿Džvg%''S||| ݎNTU} 6=zl„ W^jUaaÇuuu:={fmmMLz9Fu;:Kd"H$2> ra+++A֬YsȑdKKKi+ڮ N;okA;A>}w|t钖vҥݻw=%%%--K.0uȍ~c;蓯/Hȷ^;vիW޽vڔ)S? 555555.\_9eee<O__ϯFg5~(tHLL0`633;|0b8qbjjjX٘r8mmoݻwr{$'..NJ#G<{,ԇ˙L{ꥮnaaqQءCխ:Ru M{ӧ:::l6{O0H:F 'pL5jԃRSSG7ydU@rfDTqLI4+(*24VVV`B$9ްn[וH$QQQ/_={%KްMJG+_xQWWԩS555w޵7Ph666/_}ܹs'OкBX}ϟaT*ݲe˼yb1IwUX#F_ݼy9s}kkko޼iaabcbbLMM\R[[{ SS'NH$eP {Ν߿ kD"@_>euRSSkjjJKKG]]ݾ}a)~~~SLino3'q*wK $LHH~:E/wqQ\ ,}B" BAQBPA+V@!$h$"%b RbZPAHgi{睻eX$̞99yG ~ބ)))(@ (,,477SG ޽{s۷^sz^ܿԨQ<o@ J(V%@0eʔbt G FZZ.<==}̙H~5TZZڴiHJ!$+++_(@ ˗Bʕ%]>I>]#|q|q]b4v 0$L$F򒉽Rn]@RL++ׯ+NƏJ7:"N=0S(j`@ b0L&$Dmmmw_Lfkk-Nv (MBtJMJJ8 J$*]tڵkgϞh)))GB׫\.WGG`VUU৴%BR$o޼9))i…SL5jPZI{!op@^a$ Tj)F"YGr&RSS$UWWt3v7 yF0TXb|zz۷o;::ZZZA|NSv$SܩTƍcbbЎGA+k%J...=P(ǎ#nL^Ыj[KʚD+W|ggC>X~\;WilF$^brv/S`'999III***^}>&MYfsAZII ,غukAANurrBD+xԩ /Z#ṹX蔉 :ӃDfaaannaXyyۅ\yI/%܌ɓAڧk-шRږsH.ƁT=ÀWcFFF644ttt\~K\WW𐐐;wwvvrܛ7o.ZTzLLL$.)~u1́jҥC;wtww_@@@AAAwwwqq/:ER QHwqqy&jܾ}{ĈhIH>dF9sڵzzz&(Ko #ZW^z)mKRM6ʆrH.ƁyF`b·:h=}AEEEYYyҤIOhB3?3&/B]]]EEe֬Y$ BHr͔(^SSfKJ5ĐǏXׯ_ FttީSi)ĉcǎeXǏOB(k_nkkf>|(dmIHޛ7olk4TW,I&_zѩ)bcc  ;r80 <#tQT47B=PJHP OCBhBrPKH$U>w3lB1 C;Щ^K!"I^MRpU=4G{Ub+IO6奿}D$]>G`Rn~**z& !]4SZIɼl2&IA^K!"I^MRp4Q(!(ܟZ';V^ .ѤWUKߧJ2L+r8GxWXaÆČ=zl (IGGp)i~QX7?vvvVUUUQQqtt,++C`[? > ͐f'''ahv-I*s 6LSSsƍ-W`hO Hu-`(BRDZyb)/_9rdPPի~Iyƍ#G~h4www??L~]lp8bZ[[D <}===Y,S(/cǎ}ly CAMI|FGG9rJIIiڴiQQQjڔ!\. G@lomYY ZJ<|PlSIIr~-g`{h!I1ctuuo߾M (((...SSS?$)2'0_J۷o͚5UUU^/_r^z5bĈe˖ QKKر#,, ðӧQb JݰaÆ `ll|U$6= i2 !:a bz̙3/^|Igg̙3W\9uTy e@{tA.]dkkaXjjʕ+{}7oބh[nܹ3++ &~H|||hh(a~4~4>>֭ 0$l6ٳZZZ&MJHH 100ؼy39ufmmmuuu555Q7nffG0i$--- gϾ|yss̙3?k B!,,-00CɏR(SNUVViiiٳg[XXTTTtvv&|xNNN{xbyy9Tʾ&0hDDeDDѽkkk_vM4'Od2q$//ojj?߿ @yEFFՄ=(_|HMMΝC___aooZ[[+)/3>rTcǬkkcǎ# <>:}tGq]]7|Y[[\̈޽lٲqM#jbt333---iMMMKKˬ/\rtttttP(</$$ŋ$yB]pյ… rrr5ǻ|rdddYYɜ3g1N3StL cte˖:!///_AA[|=V?buЮ |PXzq~O?T^^iiiFRhCk׮|~~ ӃWTUU7lpIUUA7))),,,22ښJ_>99iooww{5 7|gΜIRY,:ð^uCLzzzt:xduǏGDžaaazzz %77Wi'NwSǏ럵cCCí[^|H͛ $ mC [6lXJJʰa39sIMMMUUq޽'N _U 3f0Lo"no=`ѭ[xҠ ???nbbps={wuuggg/^ڸq#WIIɖ-[Y;&'';885SRRHs_ۻ ֮] UsP^^nnn8PT ׯ˰7:yq ϝ;G6e%%%}}3gX,V\\܌3у;--mڴigϞ#:uŋkjjPxOOb2L&SW]llQlll١S<OII egz###$ԩSRGRF2XI\ZOKd2R(O?p}'ި+Z 8nq P(=z45jTtt4~tǏ?q(_~JQQQAAa?3~ѣFb0cƌ9|0 455vhkLMM%q666fdd,_|Ĉ CYYѣļĦ^iJXXo;@ !EEE<e0hK^^12֖ohhx%9##CKK+99011r(ѣG>~xŊ|>W!fff7olkk{ի]]]|>CBHIݺu-//OOO/..<; È9իFFFHJEd(lV^[OKv}!ZfMOOazzzOniiyժUPL\+t-qGvk @g7h755{Yt Wḻbe <w}w+++*s|L% Ҳ;++kǎ΢ӉL+W͛G0 p8uNvqqA|||t:6Y6m" 4ZF.d„ Hz}}:d2;0%e7mڴ]v999}g[[[ر7΂ :;; lJ 'I)JE1[ZZƏ_^^9 qQGG1 |ѣGݻ'Nnݺ[VVVGϧh aXNNiir}}=>:rutt z[[zQO "L&=jW^g!\.8ə$TUUU\vcc#yv*++)%H֓RbfggAR~`0ꂃ322L]@%5UJuqqYp!z R_~eԩ1N ICnF*qp>_SS#ǟBM ~;K.Dh );2 mxD\YIGKIR7ntR:~͛7b CC#F(((x__:!{NEFFz{{Kz޿_WWW|B>ۢOB$?366*̋cDzk`$$NNNȀ999{522RVVf0DCۏGkff&moosrr5k_|; WW׬}Ŋ6meܹ]RR䄄ܹ3??޼ysѢEVڱcG```VVVWWן>]]۷o?2;??b???___Mq4\%5Vz}`0֯_n:|7DCCCGGq兀CK'Z믿{.277urr"zyy8pΝ;T*444tɒ%ߪU***tuumW_t:=,,盛JvYVVc'!8[fMUUab$e|r.ի#F.[LcWW+Wzjȑ)ZIzUի;@p1L(\ϟ?/544lӧOjЊO.ʕ+nnnڊǏ?t`4jTUUp<{l ׿222z}򶶶v?>>m۶mGr֭[lzzz$=9sg^xaggP[[+VV|rQ?SaaaCCCJJJnn;KHEo"##7oӪ;v>>/m۶k:ZξUjj* > & >?߼yX߹sgqq0oߎ{XZZvwwgeeyzzFFF:;;STmmmJJJD\4Z Zb`fddtq)hffGŶ2"""TjNNΦMZ[[===aڣ0'ʼFFFuuuO]v577gff644466fgg777^RRRf͚z̙Ptj-l޼_gf'''jjjJqㆵ∧&MeaaqYS"I3gδjll|yI444 "08>˼~_PFhQ6`sϝ;7|fϞmaaQQQG>>۷oU\\ܑ#GѩSNEEEIYM1鉎===zMr;99ݻŋP)JHHP[HH]xk)Wz^ e<ׯG嵵ï]'<~ɓEG.$&&I^^ܿ?:naa!''gii)$ B/_zxx|rQs}𡯯/ȰwuuؙG9T*رcxcg{'O,\pذaJJJSLILL PSSO[[[W\\UUUݻiggf]]]kjj'O7ns.L6e%%%}}3gΐl4-)؂"rx***OdYUOVp;7n+W߫WS(:??q 6fo߾Iye˖ԣGO$@kKKKZSS.DީcǎӧOI ENN…  … $,YbkkӺG^zO>̬Ν;]]]wFV:th޽o޼y왁֭[wO>|ƍx~|V^m۶pR[4с7CqWקH2,'kU^uҎ9IPl2o< DL 444P̚HBD\RpB.\.WOO :b} N<9l0ʃ>3]@ h2 2~r:d2&NZ Ç/..633C ɼrʼyh4agnBr㱳vqqAq|||D%%) v!}*AAO aPLP͛k׮" R__ooo sss8q{͘1C̙[ojjjgS2knݺKUUU_SS_:;;;;;: Dꂐ] E{BxzzFDDh4ӧOQ(ZJ6k֬oo---xwhKKիFyft 8qbwwرcp#&'>>~߾}bwF߃])##㧟~ںukuu׊+ľy੠G49a喖۷oh999III*** fgg!'//555B5iҤΚ5שU$1%Df!P!?2R˔2.Zԩ%%%9rݻ cʔ)WTTyuww7V4(d2njsyss,_<,,͍Fq~={DDDXXXK.tqq-ѣcccgϞ*n YȠ'BaXpwu{!֭[;w0iӦ%&&"0zh BCCe[jUEEm۾+旭-N +..恁bh$1׮]+ [fMUUar YȠ'(0ۣ<)P(h2*DSIp**FIrt:0$wTBj")&I8}*ADAO =J 'bAxnU>Ch4hP$;KI.O!1h2I? G"K.HJ/ Q0`h38?* 0t?Xd0C811q˖-7NG{Hd6@/ 3g }"1|( @{3f`2 ( ,+..n骪jjjvvv̴cꮮ555x)S())9sz{mmm@@'|ڊg?uTeeeMMŋ kllhddgX<OIIdyxxUYblG_Hzzz:w7o<{~֭w~ӧOqF$~[zmjjjï^ӧUVV޹sk(UOOOxxw}WSS#UUU___%$$ ӫc0vvv...hޢ"" mii?~|yy9Ng2%%%&L@@!eMk.'''$?==}߾}999HV-Djjj̙si99˗gddD<<#xטFCCB7ֆKJJ,YB?[WWQ]]tjP(x*MMM\eee666STKJ/\d2Ϟ= Np[=&);tN@\b|zz۷o;::ZZZB_r}ݠTQQ .+@{;&MYf6rrrTTTЩ>@ٚgooကsss_h~츻>00 m?:]0xP~wOjjرcl6& (Dg,X2gϞDNNN?~YCCE.++0 EHIIqss6lѡC:::䤥999ijj*((XYY]~6%%eذahtttu{3*sYY1_&IR/Od2L&SAACڨ#?gϞ766666 c}vΜ9vvvsΝ3gN}}?ۿ曆UVyzz MCANNN3g믿***qcٳg(V- #!!ɩʕ+4 ͛7555'OD&$$,\ʕ+looocc`gg7|T/BA+ ^(𘘘E?F}}h;f *X{බߊ;vO?4uT< ###44o|~": _<@ زejhh?|>FC1 155F333CBB~7&k$iZֈX[[޽{ܹ@{?ܸqcfffxٳg͵,,,~'JII5kȑ#W\[aݭ7nܰ>|Y\\Bill3fP+Q__I$ō7<<gϞ߳g' AAA/_tҭ[Pŋ9rSNEDD੾CzTEE%00|藤}W^9r$==f/XܹsĘΝ?>dscccbы/F5jݻw!wOb0ZZZ-*((8jx(xX'$ed ***|||<<c?}('OE'NMJJ277;wS劊_܏ O>=>>411ill֮Euuu|I~~>IHHLLF1QWqDNc8wp  977)99yȑW^ŀwLcc#{EOU\WWP%xEVPP`0t:۷xkך Ν;&OK~W-Ztd==+WEIƌKpUPPxh|uu5͛7jhh#,KLS3gqlluIGUTTZZZknnVUUd3f(***((̘1#>>$E7n!G7Bx<4 /TIlX?*MdUVVj*MNCC_@kllkZjӃ{G@mffFðtggg@ yu34"*++5|Xt'OD'NذaCIǏ!O<ח%77vttX?\R)SH"gZ[[; 3f̓'OϞ={#H`9sիzzzxg,J JlZ N:U/׿`W5G &䈆MLLD'޻wOy̛7/!!0o2Mkttt|1V!ѴgT.1t޼y0??mٲܰaCPPPII +))ٲew_;kwΝ{)..joo^x1Ff͚'N8qbڵk/I 蘕GsrrΝ;w\;;;<‚ n޼r;;;322<<>~„ rrr#G>aؓ'O?~,~|?\NNN]]/HKKR~iP 0 fQ8 J9==}ܹhQ! #Gtww3zŋѲD3|<v AX`|Q? G? G((~l6[~~~&蕦&0~T0 #Ge 0> aҥ`= 2":$(!P(iF-P1 s C ? endstream endobj 339 0 obj << /Length1 1597 /Length2 10243 /Length3 0 /Length 11278 /Filter /FlateDecode >> stream xڍP[-@pk58oqhq'$]K%Cps923g潪{ӽ>ٴTj3,HHq@ ȉBKeKBvq8 B ȤAC#@@ !.i@ qJA\l/yu038XtH8]lAdЄۀ^A udg`9A\DY6PkA rM emBb /{s닋 xvX/pq;qdnqp9z8Z,mlPO( h!r؃^ : +0ԕy)uE~6.`{\;GϿ4,ܜصm ۼP#C<@ v=ͭHS `Bgc ~CqP7?P886P?_`˿K]l<d2aG{bvuu %9)[)) X9y^nbT dQKE`{mA2`4p?/.Gd3eуlxg7n@^6Mu-$u PˆH8Z66` 5_C.qA\mxp@^vQq}՟*JwJGsw /`?g^,!.(tO`W 菛[rحy6//t|uC_|U$s71~ 6GY ֆHznLn2,a &1Vg\K$ tc-o0\/R>6#~jNPo}0ӘnA'+8%G&c}t oPqvPý-[8SͫP6iTkDGM9em ~&q+N7pH3f5L-r 5_rlC(u?P X!u9[~!u`pbYqXNIJjq.¿ej? ML8#)+2L No@޹+-Q ݐҔO՝u$f? ZM~Ji)w ~c!.ϳIRViT^b}VL<+?z%1 Gإb9Uc@M%}"ژb(t( לӟjE}/fGQl4:uNati*t|MPW.Qw~\I&!P*m4H:V+P{}"E[nk ~e'gڽpYyh-FZqK|?%D5ӻ3a[=]b -Oܾd[SJWNJCeq~{i6xw\OEWsZLa{[{]P7'f ӥvSP"^DHse#Z{7dp*n [ vbV$EWVtߞ.98 sݱ~s_j[q܋mjˇի]ò.U|NOMFbkh=TGvP $ a +kW''L;TH݋[ø~;aɥ3V͌~,d!> h3Xm_d(0}˙X@mƅDb%ҩiF1?0dƵMzyJ$*!.ROgLX=.%ʎRDVWBI ?@OyE(7",5E'H! 7,'uզΐf'-~V p wH4CȉT8 wer^_-VUc6ɾPuPn`ON%NDDn\:[LW d"}5TO9%Ǜ&gTJk#+q7plPR#op\|F힋(,`Rm<[mɢ4Z{ZeתpI!j: `R:G&RciZm )'26YFn$8M #sK u} Ϡ+C1SDTmkۦV-(RV!?ѩhɵI:[ K[3W{Msu_ƏEB? 5E5PhU:tWe3V]DruMMC qa6g%O #2 !Ƴٍd>͂o>8T&. 1L'-ΰDY[d PWRV(fȡw=1$?\vmy{T5t1w+k籎Gc5KB El ;SB% r%Jn(jH-<|r}>jw TR`.5ͯaL܏ΈʎFǫ~&ŧ2)>v 7| -jlCM#%?iaF_i+ -{ %(tu°AeC2̴aVcPG}m_q[}C}$>*bs:Soֻa%!Q}M_֝luVK(s ?\ ^2٭WB_6]pvI߂6I e )ZfΒI !-'JO͔}鮭Q 3&bgQGN9xdm"'t"ħM;l'&)i jW,ӽh*7B-vpUwk[ۺܮÝ[q GIy4$1 7{݃|_*LEM9>`2T}Y9p>D}([,wR?iF)e9{$Oz6>d0i1`-%yf㨀:T؃ ʷWGjzt{VޛIFhvpBJ;!FGK@EZP'U:rK92iձWjIo8?{r&lsT_)}]g`ìi#U{*i,#O.,ʻduF : B\b1\ਢG#GBƓ/ONۯ-:I=87X7YRG!`f`KXWBXfH X5 vtAC 2~2[8k4,ﬕP[_c٨G*m]Qp"y!+RDDj= J +>1G{IO"_Ł&M?ѼQ]SON/5z{fD|CpY}k@ʞxQ]J҆QqfO'ۛTFMp .t+Įe/͟J,<MytlLB: K^bs!t&JWkW7$Ž5O<.l*]"-"D\]طO еZYQČس[>Nܠj6Xk(5mE1~G+# KjfzJZ{(SoJtzFKzӪ^TkeĒ`ǚ#fS`_\N Ut+8)aj{b G{a:qVJR54ƔG/5Rp1KgKjq伝33gX#vY&1*YS+$VA=f9x\Kx#URFUlQcs ;Ct-{墲Y9v~ĜɂFВ\HRW|Ϧ{㡾>[)7hΎ ?12ο^CGLb^-_-_"W{}̟KĚ;ːoyLPq6<k\0(0ȳ+z?ABA]al}ui!™oW,Xɷ]f jiy7oʭ XՊf ( Tf3@lJi,}hR^(IH|Y tAR;6OJkVcipBI#_~ ӄj\a[He^kF ~@$gȺ@1֊dPIi1!V>2 Ҡ0Ifd[c#>:&ךS?3KB_;  ,;XY7-4_RBF_܀+ph3"ށOjLJRv90u:C0,aan{PGԗM=GIk>NTECM>[E/ea:z0M9s,`Q:};~mMW)ؠ&inY=Vlo: ͵bS_qdS2v/BYdSdUtT?R0N 9Y:zuJDcS QlOS0>4wkeeLi93٬*x7=,(yas.c%Jr8S@ȺQq A$r 44 u.y|J9k7)A}cws'M S"' !}R%OcjgSN7'&UNUq^Bb<p]Nb+ IUKƞ?,b} 1̌q3T5Nuۈʠ)nY?9¡ #:_8~k^gP6+iqloۓ8fQN ߇4<4{:0ԫ3" |}7̘`{] 0'Τ&QqwY|#aZ}02#d4C4k0#"U1mhlLΛXM_|˳yI0tdA?,ĮdE(5 _~HZK= 90h:LK}١>j(krnǏF)84L;++O5(ޮ]~̜dн0<gkٺ,Jy.`9:Vg~(3>"eBu_Mػ,zA; ݟZftj9 >M . 2do~)<&]41!P۞ Lz<1He|XNܢOz!q uk{ӶXi2 RePjr-qH*\656B~Rm7}pCKFڲƹgyLSw5uvZ[ ?UC{6c$[:wJy7ŵptwl(}mbK>:yvm;,;ag~M95jVχO ._D/T~4}I fQYB/KCw(p9KRL[ë!#ESGŘf)5~,nq^a%el^CؙMIoy6?{p1i-Zakf(>Td"GYDn65 JRF˿H`1DhXrOqT3pnYNɣlc9S+a( "e J6]~E ~%~f.݄. %1&'+V*Qf%QgVҞi^RҒY\S_%q>7pNva %Y쭥HTs9u&׫(̳.RdG zW7BJw>n3R| g 5avv+ضJ`W-S~<[~^x*(Ʒ~AMtqf6aiF*_iߵ n|cfA\Db\q?DsYbKIfQ?$ Ү$hI"rB`4_al̠܈F5k^V~JA _˛N:Bf*Wh:.-pA15ʗP }p }\CV|~0m#UuU|yw__p>e%C!qXB+4Y75+Kmk])+d*RJ~XZ^5i KnMj/0V9j9ٌ{)a IȕDA@\}. {;ylV"t[}D~J5mednr|͇zzdzM$XmY;Z'2iI@jwALz[NŻ11A%!%&Y%Hi\Bg{q~oקNc;8ub V8&^.&p{[Pݵr/*P5&Ҳ\ui}HpkAX'*OLc[m-I&VO =7c*UB,p30O Y[wT.IHg[^CBұan/{Y]PQBE AsxCJLY5tQ\}XZm\S:nlvBS[h|r-*Uh15v{U=f<2ӁaυaXS%fMJJ@gyyPNFܽ2 A@"o|>*=T{Wo2;VL6-.\] o)PYb)D)} S}(:Tt>ΫdIZ[f Wѯ2/6ê};LܻNJKks#p;( ،r8iKV/Ixm`⯥Rz,Bi N2Ey> stream xڌt  Vcgb۶mcbcb۶m8 Mc6vdkfn_7TEQBэ (`aagbaaC԰qRj q]&t{7TtrȹX\||,,6:@s"@Rdce?4fV^^n 3#@fm hPw2p4nn|̞L@W&'-fj0Et75&JNn@]`ocfhng*-e/`ebo{og3 `icoPR`rrc2ڻ:=6@wKDUwjqvser#_a,h.`W}6 {3{vNA60wwftqqͻ pXxY3@o%_wNw6?@ Es37#Ÿb l, `fh3K*JɉbbN^_FNv#'+8-U:?e-"޽flhA}-4߀o")w{42lmn﷡~!T_-doun uom\l,Ul̬D{p{G 'W8FV{93VYt4s28@`l_#5{LNn.wrK'_0%0Af?,_ `2;Y0A| {>?= `V/a0AﵨAﵨA5{>"w޳A8ufN#1Wd忖{_=_;nb㝥? ||gdNd}''绫nCOwgQWG wG߮.lt?Bn Oߟ9n 󝏛?)w?fdl{w+;Q~1-,,Vl?uj%dܟ΢e]uFMm ݋ J܉t4F~IU|{6NVDX.=m"'d9{q ,tqAQ)9(4T}"bi_Kz1^3 b4 ƍ u~`D.4Wo-qGk.,Qβoey\Dl%RP7*Ѕi@8qx5lDرzA.zaw q j OlB(TxL-2k=q0LQQ2 ^ous[H i~/ ו#G[ 3!01r7Vk~ڣovBU6z}P޾*}<1 ^38xAZvw[1ַMȱw!gS/nO;3EUq P fDSGZV<M5VE!7VϜyF)L[KH\װkE3M1as-/ di)pijBF>f 턒 [giz6]"<7S$}1Vb/њ3P:8 ,hg *|mo_Pؓm]ka ;shR;hVAݺ*a1dnTbjKBQ?n[; t_c唏&wbÀ]2OP}U>1NIY,3/%49!z1\+9r}?HwtkSc0̊Őe_ :r [xrp"?%8D(E8f?C/c1{T@A,Aw+prgЏxvdjF5>oBdH0bO/DdJrȱ9xg}J:ҫ9NQw8J!wPͩB[!h-gC3+ ǜsIxC4IG<QX> `ePKqs}=].a }z—#M#ww1٬|V #E(SZtxdn0R~po탚+9@h[fZ^ -Gq[3C?QMBP|3CE#ڴ7PF?,E!] 3d!/F1 #|gp%X%:򚺫=P%)IŝP贛z;,'#=GF\Gi y<6Ddt\w)TIdɍyeudFA!/ DWiU2ky|>59K9z)B9'.ovx Kd0JH~K5(F x&]r橥0m+ip]|Ecny|C-6Xr6y\ƳM(o:Gphi-.O`864=U#Cj.9M'Ο p^A#j V4+d(UqG<8ދ N*+0%` $d/Z=HH,90~ɘ5_sk^-:l@5hl ir(e𳷄bu^K|tѳ'gd:~t3-!zascGv"U 7y؜5G:6zto` nM-G/$XDP5\t|0F T7D{rgh2^xMS3ZJyKe6;[fͤfnP`Aܵ;ZMw=2gH!iO18Z}\#SiAzL? kG+UĢܨmsq`yc)\!X665a $-\GfxbЍ ]Ɯ (=9:V],8zaI`xجק2I< ZjUIN)R3B !La}]`/;Y+Jt#5H+\.dm Z㩨 *5Jw/,SpFO-[^r\5j`Xuw eHc52B@{ ۔Z$7'֋N:3VIL cR*>lc6:G,֙J3ǝ(b3Z E߸DY0դx 4|h.)6Óo{la+ VN) p֢wF=B`MN,Ն'ZPր}wlـH8Ü^ I񻗜nF}юr2(#1`*Iœ@nB3lM-VSES4Q>\S4:y0;z߮w9A&F0j|q,}̽ 'ִ9uSi `Pe`bHq졝Nb.MuDy]TY+ֺ& n*jbRy}`:8uɲK̈8cvE7tѿٓB~Q+9n<&1y@tkikސ&b oTxc}7pW`#g"C/sZ1r{N&dL: oNa)~HNH˭vh/ `R?66cvm4㈉O y (Cwqd?2<,2 cmӺ|4e%wb17M9{(ذ6K=:ɷah!׶b>n(yz}80qka8GD @JoOWk)vg+XbEv& ws+Qh,')l3;܅_$&ſ=irҿgQ!s=^=ԷHyij!ٟ#PzA[5/r#.`ًFNIJB;Cت( ]8pp}VFb#[LQ^ >KZ=dT}A{KbSơ`5TEkfځpM!9\o٨ý̄n `}X1爗owiqr@,RguݹkY>}ѻ&:5vuVMDUʿ[}.阴`63Rĩ,Wqވ! ˘sl &u3HY׈ֽ%[ʍ\_Q09k X>%u9ބFFRZ i4ff E~@'ȩ`P}-1z# <$T *|gYa]> jO>!}iQ}-Q \1_V$u}}дwEu{㩪O#RҎ@߱-xȰi(i)X&MԠ U׬3K)-_-pTzGI8H+zYޮW@et SxٴxL98b۱.t:'d] X#gk+ 9EUcKU ""x9:e]W2S TWaBY}p/L/wz!_o7HpxG['VIG 5'>űߔ#d36Bχuf%}b>=JyXfh8- p Z7B >JLE~W]hfr_*[6 24oԓHΩHyuc8K((ߞ(d?j)Wd1ɶESUxB L$#IT3`"`P3ڟ蹸4`Gb63p]k}g>{kD]}4wY뒵IyTL,nǴeIhw 70 9:y~cȽ/7tњlAꥶ l6IQ&uxstpãu ;K*5?2HY wA0X: Q9<V ꛞzlYH N!ebesnJ]ZB`8`lY\0ݳD*LcB'Y /.ܫOaxhΟZ8KLOX7π'uONS#?V zG_RK ƁyZ1Vطuz`\U&9o`.>M[څr` ֙,/;},AMV0Z: l:ۅUuշ "y\UUUq„}r4$\'WTn'?1[3r,WN D^ew%̌e o`y,FݴL'x* [߫!vJ*P>nޕo^(5߾}_]<\7XT%[´ O4Px)K>м$l}Y&~-U .&G`]`_q!1G;"*zx+٨x{t=Tq-"g:1 1)،yj6vʅ췒u '5e W͆v*TJVoc텒(ͦ0e͚E"fkbQ+.ӷ ad6c9E7 MB^%gLWĽ΂h:E<&M2m`;~۵Sqs Yt5u- cPҕL2+CH|y4'UB.qNPC $Bײ&Y\#\;9dgAKc0ԶeO_$S^g~&7dbW=W܏8_{ /e>x+eNǞ~ַj1Ih Ģ,`~=F"՗5dd^,w7y2oRҌm;m+dchгfTB'qHAL֖F .Dqs H@ @e |xIgZKtq<IH5A<:çQ[7v1U588"m,(_OyswhmS}Q&` \Tmgަ!W(#A+mwkv&ŶY`ǃKMɋSOHB ~Öߔn$p&PTf%m}=DN_\Q etЋ߽<q=dXg/`ƶ/P¨9`Ydr y֔jz ¤lLFe(!7gv/Y np,y2hvH;)zsNƔ|ͱpi'Q q6'irvenhF6:3Uɓ&o!h8Y^jqV!h#XoH^_-_SkLNH}ԓh!O.pꐌ1e֮,P_2sѰzCUULlDd`Nު6 QӖ.E mϥ7pDFӦeG=/f$ 톑/PR2jn]^딑@5>W6M o,6{#6uP8j %5\fes^ÕA]4_2s _m׮j%&1|Q&ՉcC̷Eʼ]҄5dy0lt=u Jl̟gf\l x s!q |ݷA7ںN9} cKOaz;Sޒn(b18g,&:rڢcרidb\Ϧ`1v@Kg1ܥLk|=rzLC %uE=XGbH_&NvSxinvVb1ԁ4 } ^^_sބ5Q:m\Ivgc\ROA|+HhC B:Цt^Da Ͱ2Vr-wЀ؛7UgrVlfkH6F"!7zGO?c% QZB}vl~RSE߷F$.%zfvĺjJ!#Oϊٕ] ䷖\)~aSqfy~8a}Ui0>*tؘ^B+0=ZdUj>b4=W9Y1c$ +d7{o۫Q GU|msrTx yFpR/54=[(To΂=`^,'pt&%ݹ]Uǵy Zpö};Xk24szO_0:9r`q郗z8 c d:ο`Z*'ÏgۚyY5$FWZl_ް]VW4 ʲp@C S| 0xޥ<1"M/I7 f%`d-O 9D NbW|6숖Q-Tj !ܝ[>"Lnftưք7XHuwJ֣:@Ƣ ʼL] ޶FUg6Q{7xQj9|Ul)M;7QVkqdW`b̠^ NgDFNCe{Dd $.~ݖg(m>5v,tw۹p yQFx Dfq@+\;}n.\QC)AJwDž'Wijd$)j"Յ`U'xg|+fΝj o-+mc~L:ss&XiO|jO)Q\sVs1\LA{ݝk'bjYlmQK&W7Y\r(T:/ڝ8$ś:AlYf$l%LCK4.^_P<ʘdcD/$7H3 |u\]%2D.75FԩEg# oI:\Y7 3?o2յ' V%׹sPTz}7!`zs+ì]gY؞)8s_b B>o&ʁO]>X*i.Aꭻ%2N)"諡V[r.JS'C5K4-0GWkH,tJƨ\ :&UwFPvCˎ*Kyr1Zvd̘dDo_Sɴ;\1\0 }F#2jm~#->ZRfXI αڇ"%-όVPqa“8ӃItI(::VDLl~)FT{!Rw$}0+TG&I/ɻ{DD3A|D cR*64(uw!^m!3[W8=ĚmJXgϤ@p3V /צ^ l! D ZkEzs,wZ2f|vMxMiN-ʞoC:nZOw6`hv]&x ݭȬ*pz98Puk|ʂ߀)J*wEM\t=o~bԸTqϱl[ ]$>Qjmug&K0cjSNLt;!]^=цnQGK"D%J66ۮQ2u`p#gOU *}sv+վmXgZ޹AɊ&͓7ľK>11 V$tE w <]"UEzD E_"zE-0zޮ\ CT٭Xe}v%M ԙTQMst^!]uϒ(%&n‹#*$:,.$g: WV28Hݗm50IݪmϢ_W~5]~i!UXf*?yKZޙEa,`:pTY#% N+ز-aβ,#c_ɠmuJQY}3UWe)VƬɠPc$T-ػ:zx:e)R,u'C-4@x_)t ZkU^W˝f92.\"+BW>PIU|5C#1La/R*ّ.mDSd[9=] H`B>*A"7(q,OZCgL:j]7 /ܰk< ӣvܓrSvW'*b5 :D Ow}M9 53>_TQ A.̲'|mw!ۯX&1cSaVpͦ)fO)?4'ȟYGkSɠaΟXHY6h  _t"bERtzWya9x<tuy2D+Zt=)mfp gFܛ^}CEG+u)띿J: Sj+<謼 P ?뚒$nmoK™DIdd֔] sn%>MKz^,9F_/!ђ$OAʐ= '/f7)׹/;*Z&Xϗuslu`ɮ2GLq`,nk ]ALz9/`_#K+@6,篍D>6^f}I"DS;?ЀQ8Knq踃`$Ӱ8m1GKySTf-ߵ%lBR$i+GDsq41#Hf$`ƛʯ1?(}\nZJgeDG|hwʑSEjIdSBCɒ 8߷\dԿ%p,#_sF-$"ۼ'$gΠ@텽k%_2[C+y`wFԯؽSh4JZҸh9֛XKmbR,}Xھ0\ULeBѢuG6w)?P‘K[-(p!jRAFlo1$nT髰Ф.;W[RYch^g]VK=(iֲ5]:iCt+flƘ4+k㋽5<~ fR2e_|m,Ɉ!_Vs ]409گ})4hu [)-ؗw'ojdf:RoLDT2sM%Fc}ְ;B;_u}^ttˉ缝y3[\fҸkAb$'2D3Rfw Do$LYmnvMwvN-fRO{}8f!/!)>Os!]p9̕ئb&>6mŶM,/3/K/ahMpt1\.w {~d9?qLܨ/'F t^Y^]yF.͗@BhsK>6%rƍt5r)bJ\SkcJ>n6 GHI.ЖAB3Bv=ze9+/׮d!S=Akښ-ϩ XԘHaզG7WىQ{zgL)P2HQ6#oW;E3TOt7p?6,u8%o, #ƀ Uj;IEC$p!=Cd*FJٻVw+MjS)v0Y7ϴg[ a]^4N3{UQ&/#R[$OI &_A3mFIźmex7Թ2kJ@AviB)$[˦1Qv^-mdTPsr7!~, v*b5⃰7 AsAE/h _v^[-W z'ޚ/"ё/[& jŴKG:"Lƺ52FJzV5/37 endstream endobj 343 0 obj << /Length1 1978 /Length2 15812 /Length3 0 /Length 17024 /Filter /FlateDecode >> stream xڌP[ #%`ݝ4\]yޚ*Yݫ{LANB/ljk 9330D唙LL LL,p䪖NՁ ?@#w;Ov09x9y,LL!:Č\,Mr i[\<Lܜtm&F D#k%RPY8902282: P\-,@G ` _ؚ99kK =d tP, PE%ldbbkcgr, Y'7':/{;ʍJwh`ihiDƿҼwYd*jkc99U/ [W翁%/vj K{ggSMṕNv&&&NnVt3`+o'_wޞvvw@oK3  `ji0[n _@}L}>^ k/'"bgcг32MGVE#G 3[47?:\=T^j o>@?do6 gkTF6&Zپ/R5Ze9~v2z_ah(a4Ut2 [[l| g~WGLlMZ<v;տ#v'm#=.`f׍r2 q8YAszg*q1AlFQEE뿈g0ޙ&El'sla;F? 3dy;#G?(,F{/L?ﺾ߅YߕQƻ,?{YvG8{6{g{N |/^=џߏpQ vϜ8;8~_߿@niք7Ȫ6Zϕ~w|W#sɡcuUfípp8Ս2ыqK'g86Ic~X|zU={/u/-?s읹]$KWFCw8dK"ufsI `hݐgongоMIyDzjoD?y8vhc@ޠNQx$KZ,.\Xtk+$HJpQejq]dIQ $Ԕ4a8(`VD;հ~tߪwY/sO׽f,=׆GBRZF5]i-tWWx2RJ 41P]<.Dq zGx]D{W4wn΢.XrȿH9?/`7 C[ l ,e<߬b+q'b_$+d,ٻP9n[B-=_x$~H$0`붬LDV5Ld8*gPNeo] izaIOUE\mb5TǺ?ҕ~#,\9 Z[+ũzRۡpOMIj1ܤ~+zG ֻ0=MsjӺBiGA~Oj޼*\_1;8 B C`D PPB.[H6m%H_[q\ƯۥN!&v;̑mM2W 4XcYE>M0'F';zЗ8,X35loc6&B]U<8uuRIjVTzLکד:_}wxn^j/*dIbܕD=1B%̫Vo|<~Ч/ &퍯款a1s}|='h:CpP3 `4J'Myi^ l#Aƙ)]M 2^ʩvjpDŽ\wOuMͅX'sk^Y]3I.A٥7-O y^7tV;,i-UanO#2Fa"p+TH2!, L3)Ȭ˛>mtadž#qapdF(X(KMS{^h44: "g_6G/>04E^3BN쳬+E9/5;x4lB% XB0KHu~ýB=8n EW 3ri8GkCXp+8;åN[֚sEi["k" <_lv $gN MkKN]rl  jKdݯC?*Ba&̆\ WδHx|=l۪6r RPp4%&~l_moQHH=|S\.BnDaD+DJMH&ȇFTw&XKZ0 +Z,zZ[.o#c4hzk K#j`Æuz$hJW-U.r!*u21U0i':CZ7Z@E|ˆEPkq p5񼓫9dHpm%qKN;oə]:Ԝ}9,C-F JMٍ4F( RZ6 *Yv?d:\EКZ|2i=܋]~ԊxT~ ftm8jY7'™+K^ 6w]"sϹ+%䮢s "Vd<(9˅)\"1amwNXٽTpGzIy -tVk_R$3e:i&ܥv,m"/W ͩK0萜t*$yɸ80(m+-p]zn5#dE E,heԲU}q=ϷѪ x){0Pμf F>炊vXߡ9%- EfC2 hտSyIX^"eob5eHX=yZ,#~k^%kHn~_p'b҃YT ?_ׇ8 2Z&,<dMu1@C Vegx{Q,K%WljT9Gy.PLLJ:9{  3[< GP)_di 4jiTG)D֢T~7G݈ %Y27K! _C'-0`!v)*\8a1)M"YZOi&8qHSCY!JovjlX,BA fx,1 v7nK%_olc) ?{_ A ,tz?z4a_Ck[ z9h"ÅIՊ!5 Aa+gܛŞU#MWF@-<|ڭPeJ?w4x{YvymMĺiEvkMg2l]v : Az}(?!œ_ ;O_͘>dht}1\j<psT<;Ĉ!cR(HS~wޙF#Ǵ]Pct*ZP*"i-ByȎ^vb( LP`X_Lc{ǰc`϶}4/J#͂iW;׃mI``=̏njvc%rz5ךK'!i!o5Yzbي2.'ejW>w'WiRl aNCOe>F~O_?k^ǛdNAnM<Ѣ/}?)JFb8E5KB#‰ԵEXufH@1$| @[ m&Y>wåVWU + vlx} ۓ_O꒲tX咯%o-" =JXh4, w|~7OŤRZ[5D‡>  a@'*zB̴ΐǩ4!I=&@Bvy)tg9ޔ_&S)XyHXTFyJQOWț>2 *$pP_qӫnn:ݠgnۉ;)B'OQLnY[#RjvzKPThQӾG5r6Myh6 &:Uj})z` ||8(u|2g}ZqUa'  @HlJ I!dyDiA<Os߹i>3yc4x.bœ-{ \ ;HdA.(nPdžq!<f>RWĴ4"-lZ h?_hH"')MR4 W оp WA/3+i/f=?Wgljש3mZLx]"29Y{~@i<5!Y5U3*C'C{Y< TΧ֭Ƀ!`yEЄ|TmUD;><4w/@}mG߸Dz  ]~@!OPѫQWB!W(!c7C%Kx .͘ =šFʮbXp$e`V㧺Q3I)EOUZ;hrq zC"_])mAZ">=$]4n:DfhyDd 0 ͡wůh}AЮjT(S~`[Q`:Wx!@XӾ |h/|p#Ԟ mF7N3z.˸ 8ot)Piv̮S~Ewp&)V%.ܨ(("lc70o^WzG~vI\ѾrGZSXС<(-4^PR&MC6gj.Hڒ:r<[TF*)WG g x%񖒛 BGL^(uJKĥ΂xEIm]n .kiN4͕`*<ܦSfX;O8͡m28lHUn4K>Y\jŏЛ+7'()GryGX9 Brid_w|R9Q*Fai,{]~΋lwQxCw!Bx8K~gnmzlM6nD3%&'l?{]xO>x?h@#!*O+[[o!h s4ߩB%nRxTu1mCZKXh*cpBM0ƂYz!ǣG6Yϊ'JOe_KWQQv3 סTDB'ת 9GP |qE_Dx@țբҚL09yI%mq[ 0N_X{ϼ5՘Pg)9L02:Ң45VSF6_z,l}HvL/ĸ hF(D kFoS~>4cE߫8 W7dz5+?\y:SX iuIDeFxwEϩخrXX?":bo|TS|ߦ r0v+/O0s( MzT5'_9}ļ!kCƿ,'3ُ0DBpynC : N QUcK;9y[ѩ xT; Zuz"}vQL&Ξ.yخaD1.U:"MjS^|Xr ǝ {4n`\QXݺOJ1Ol?uLS  3sbl7۲\R⊉w@i[9>+ Tw \ǯY]/sGО 7Zx5}.׸b^)]q#-!V^*7ȆJM{W|Fl TjeFy.0j*;|gэGa8H5>-/̐FjvoT1CS9=p%4X2i*,I`.eז2Mq[PjX+U"eodWԌ7wɐP*V;[%1#mf0q5!xrn\[Q[ݾyMxI⭙nR9ORcU*>|W!,/;~θ\34bމvippukw'XfhgLWxT-N!Y5yY-O s d﯑[ɰ~>XоJvDGjC'6:;\ FIw&<@S[,UlG<ߙsVyVγLJeƢPy6D{Χ&_x_&zl ˟7bP`E^3UtR˻_㦩Z.,_+9U^ݵM0pqKN­Ium k;iO0&VĪ9u'(LӪM#I$8TeU/43ZRWePNRZB~ 'A"ga҄SV\ui'%|ZAT:U kΘƼuk1䐪+?T[Q_= U*/Qp|P7儤E4nF$XHz2]mFkWDa>JK)tti4OM΅*\Hkj*bH\!^i,y@,d,Ǘ #ϖo i8to_9ؔC2"X ;!|(r<4UmAWv1 .nSGK!`$8-| p;GžX̯a=e]2!zޫ5Y|F=Q»B;0TxTU\O|B!:;xX^nwxP~Yҭo<+ O] \geǸLp_M{y4S!&"m1gZJ2!bBHﭨ CTQ4z}4˽KP:啣u4rZ*0&(2a\޺lRG%HI= sM9.< JgGJriӵB%%CY0D,*6Ħe^7=# XsvXvBݚՂl' sB ܘ<əe`+SZ e9 %&a(ЕdC]4\ƚMO)3pS ai2sȾsUL5amr[@~9N8큫5Myver)^ў RCx[q0/qŶ?bߖrV=B󡹁ܣ=rK^#ΨJ|~HSpF|׎ƴ"8Tl 6YIZ JEc*rNimA3EjC \a'KWer )t\*KJ#kW{T:`lqdOx&4I3FՃ^V8л gM++IfJrnc\[ƱCZoX"<[3 ҴWX0>^p:t.Q:A#r,lꌍVTb#b$ -9>l7FL8fʵR-qZiÂhS/ **^6uK_n#V30#Cq%CӮwe+?_z]Ɋ#adA;LEHndIdJe} (ò4RJďRʰzW+Qje~ܡtPhώ ܷ=㬣<*:6>u-~ caJPqS^U졠 57!Ɖ3әdA/C|;7r/DRtP֗X:y$أ\lCXG:^g R}wm/puwIݷ+2[KGP>zMF<ѕ4ܭRЩ q͎юuF[`9]yM(xv5(]aJ0F6[6RF, ͜Pwܒ\M9PJӮGuVSA_b]K!IJ@=8өpQL<@."fʏN\_P3Dfh.mR#HZ"8 9I) %'PZo|Ux0 ?I'O m-> U-J^OrUg٫ȬtæRE¢{OȰ6tRa; xl };WeJ\OQRn]2l.ӐXooz<۸ޗJ5F/ f"w q PuKHGQd4 ]n' mzVj9pYqղ )z`*P:C5ɫ6p tPX:tvj0~ j3|Un2/3LrRb0 伮0^;~Ï_n+7#_fғT˯*=~K k%DOl`J{eۛߚQ'kFɀpv+caΌ~r&{QcQ}TWLi;3S0ֵSxcZZO7#ʔ]'n">U'GMy X zJyg QG44 gʐE4?tM46k` k]S4GW.懊A.k(:H|Hbtw\ÕX2IpIaX#MȈc4f߱Z?.ꥫ{d&P;u]?苓YlƃY/%ټ-Cݽ0x~(Ҝ~#Ywln OٟXhXsG@ת*7C^Kќɐ`H+ne".[MΌqWf qyj[QoU[E/<-l q$`ТAҠJ6~c:v!'$8AjAϻ{ v}!?_ԙ=Q9x q& c]zjNe.m_Sט ?DZmYW*nDa@ȶxǾ-βBc+οX. R*. 'j_#?k2V"mR)wSL6?y v;`~XWCkB5hְ5C24+x,Kb@X0b|0e>O3g8;`V\C=f8R˸5/r|e$mSf+﵂g 3);D`Tݤ!wx#*yN|ؔ˨4u#LLQAL{J2i} TO ME23A7G#2ƘeYN[ gt3\:!ܡ ȋSjř~RNefoANb ?񷦴@$$ĵ /4 ha>)q.PdAO5G]"X!ƿ E 0^1TѪY?wUB VCĤ>F7]NhcVv3G )"E'B%;3r%T71/5THi*<ѥra7+P{@Rlcp`]>Bu4C3dMכ~H.p"Y z*@~*'!2>1B_v]qnb6 ~aЮ$ށR+)BcnM(Hۍݹ'JkbÈrO1|tCТh deJuEF*{j9㞯]UVTpgݎmv$;Z'BP]tl"=!rʨ#vWTVvExYVpd+1#c6ZVz+v7G^aF K_@?p~$ebndTEa0v1}.;* +Zb`f-jA<mV:t\nփDC"WCth2]y^\I)tCj 4T#팾X[/3ETRox߸^x X}^S,辧@l3%l2AVܷ c>#g1츦KsQ@3E:ZB+>̡}*eXԋJ3XFZÀXE# >'h|ONR #+ФNQx: p[RU=BhUmS<@Z<6i|ES{\(aSjzǰR~tۡF~(zxާ@"?c7XH"ؖڗhūe*s9QH!HvQ~nٵ!FE1(=+׶L7 Ŧ ʜX1!ݧ)bq%˛} "w&Wks$㐕̝BpȤ]ɢt(apuѼwQz;plgnxڀQ*) eX }+@bxذa𖚹mR{f'>ӽrwnb$[<՟}*ŀ*[=LIq#h><+/ RXz?\mZ*k?m.rQ6zn(,uIu%~`2Xv}ف#b@S+Q-ǭ*75/DT&u#F+V7Ee Fs01,b+rm}tҷU'Zyl07C]ԇNa=:AJc% .K#fD 43"Y;,P=$lP/̕lD~B߾!գ#)?-+#W^2Z!8L5۵A"GxŨoVY~JExm#T lI.1GF#Nx64{[٤$lu}V*\#g\WCvM4`{%LS*6%IET0TĴ:Ř>0e/ge\׎=33 1l%G22aΫY02O4F{#&gƈ%|5~xIhlX5Ob }ln 4yb%VYUoC [3p~WtJWÇtK;UMڄK$U>C_:ޚb?l yzI`PVm$ͺ&yioh`J> stream xڌP\ A&w-xp' 7U[TAk9 )2P֙ ,```c``B %Up#F U::Yra 4tD Avv)k#3?C;G. @ eg tB p03wG1%/w  kle46([=͍ٞƉьflP:]&_ mWF@ P1p[lgf@[' JPm6ۀOotW ۿ l m=,l@ 3 䗡dsC"T?9;Z;;9YX*WPEmMllNX8Am{Vvn^S [_EӫZ8%E1~̀VvNt76^T=Td 8;}T!02L,F@3 [Ab4|G w6h ~ Z/;[k͗^SMZQF ٹhYLN;+Q%U0vοKe\ %@ P|Vc/m/!1kԆ66tv۰/YhbbΆ5Nb@ gcWS*9YzhtoVhVsoJQ[c;_w0tt4@`++t&@6@Ogk r9"(+^o8"'^_^7bKF,z]7bF .o"/qQ@\#E7qQ@\T#E7q@\4E Kdi9[ASr_˿ Ph+(5hS'aa% ћA)#'#(7h  'aenlmhGdPcMCw^_7_Y۹8d` hR@?,@2? R? h*V@P'6Q##\mATo2 gAVك^8 ?ΛLcZ{6 ƿkKh 41OЋ_31sA]u K0XAA@cdU;-@lcSAmsvyA=vy& t;. 9_o@w11wemP] ,z*%ײc leufO]QgzŶG'86)~BxZojV-]R.( wn}uec! ߪ٤fhT#uKHq8Q9wG9&gH*{sSz ׷$op !oތMy &K,zm:cwo$2ZRx)9]ꑑNrQťĔ*oSBÒu&.ybD#o*o^ǪȹSyKUAdTGdJSGVo63h>̉b JcYB<>$9w!9zKey~ma7mxiCCaMkR"5',B-xQ2s[ukO)3w1T^+s92 %`c B]ŧD6ބnKEP_W\w^2Е) "Y'bheʜEqbpHRA{Cz -l~thdKq?IU!=:= ox4CkXƹj7Қ;FepAeW& }^<60Lnc9!Xf! 9"?N^Q0+O"tCH-ȼstEFΘ''ZI'Wlu0s6.KS5e*pSgYs< n\jzwO,WaB^sl)vcȘؼ MQqn'`,.e'u`+P.}WK/q0Ʒ(FNC=Ja_WL%`ꛣLy) Q#d^d7'Ʉ~OPp1Ҝ~O}4M&R@ m&aXed0FFHu%Npk;#~]jxf!pvیy:6+U~DlEpɺ h[_ٰȓߞL1XQ 5RT}EecUZ.(E ?^+Cz)u7*[C S %kOt?kME .1uP]NzdsJifi?fybك _,؍iM,mtA*~> M jj~6\<o?أN@^[Щ%!݄rx~ :6^O =[XMp̏& (|z*xi?!W{;/.˛OJ ׵镼t͙‡%qn2pP(3P=8ɄC <17,"ƿk[.rU R/^I̓`Hs29+0nCB.̱ORF |$u~QHBk1wC0yl8}6&b&NMRbj5EFXH`1 "2Gf%JƫH>*L >N?iSQqeE >(EƅU;C~h( 6#T&`LSɋ³"QU1xnنO ~?v^8#}zY6~}EQS}ȠA|CFt__k E?Q|T:"%^5F,-}tz~N19>2af^5u'7 Z4CϘo)+,~B}Du9B/TRܷl;E!D^Zs$7m"ja[}تrݮO}vn&\Jh3q*z2AߥIԥ^j^ElE:bPZ%}I@C6rOT7P7(#TS>^-x׫ދfB{q&؄F8iv-Iצ$K ,{ɇ9)"%rV`aF"ކ"R~v t^ n$*htDui ':qŁ:ǪX0\JCڝbtL3QtA&* hp$2^Kk0LU]) {Lx]L9TŦAgd2T; }/ߖ"d9:nΎD?{.z[ckGG>=RZnurIK@~$o~0Oglz?Z'fÉ ¥ϗ`u5D_kD`D-x{IяaȎѶ f^;W;!O^Xķ/7X Pm0ZMc~R^!$"9x-c| ^Kq-+ ^1T齪jړGRf;!<{d"NXhpk';עj}$`.L`5Zc&O Tvp prqghZW)/3N -G|z?xR[Eqw94< 6`,fk~\ϑsdO1SnQ\6b63,%Ğ+dVu(aNbbEc;Ce~WMRvڔj  vjE'%Suܕ֭j_u)&*1@-"/?@J48m R1מćzsD`\| ыw>3p¿ad¨ ʦd)T~ 08 3z! sG ?âNG)=i-)A{D[(5Q*j볌vZS_ٍG+SRaAddN{-=Ȓ\ vrƤE:BM&Jݯ+60@}hZq@%^wӯ^I6LhqJ?Xd ?`紜si@#LGR ,ҟll8)>nXl`W%pEnLɛ")7J l^ٸ+]v(1īvpIQkMuIc}cZwqM`w /o74 O6BR$;(p?WHC2B?P+ԙѠ1tdkP=4U}Cվ,>CK{mޢ UMg"+à3~ ^\#grʕlGYm`E\DU/Bp+@NdJnZ>nI*tlo+1CA$V5gno9f/n5.e_/)ڗ_aҬEQ%45w/QE_iXcƈhag#3bV"S6-V59ZSDm$(azng@[N>p2)$8V7._xM0ynF(&@^⃯XegEh IJtnvk]%o C4!B)xs.e)9ߜ1 8.0B GKRa>Tqu$i~нPqɺ#]n: ED͑>Ds( xԿSv|zk7f g0AdN =?f̕2 Q+9;G*3Nʑ0u\@c]Y/O/ tߨT><_XeZ1 fծU5E?J3\O w5R0-қ%Fs߷YB"BS^bWvGP{UyAZ.+MjĬ\>n9.Vd7ћs>֙OtX|԰!,mXYSB?5o+i #.㈋Jh?(:[FݖUrZ+N)H ~^";M@0 >Yc˸o@^*em}ܐxYuqwCs7J{U+欐qa.Dgȟ\ϸWN C툈eG/Qde!4:fݶmAT$ Pؑ}"oX!Xz>$6׻8aե&&E,Ͳ7ޚ,DC߄yK?pD8'%VFd%R[sN,*{9΃x^gڃ1xEEQS|;l>Lnq||bM__RSʞڃ/#`;b?&@t<qSَ\*W?qx~j|ik$#E=\-A+\#M y",1Tv}YwBJ@D}xcltsg½GN” ݦFV,oV<4oQC 3Ę/4=6*b?ŵ5GkOb`hoy68*ӕc+UQ%Ёu]L+ȷg⊏` 5V4`yc?(!o&N!NxL5"`%rf?bBM۞_Cz'/1hcn#^թnWrZߪBЉ%Y粒_N:2%_Ĭn͈U*|qyGYV0-`> 7pcPuN"I%Hs#3lb^TJ*}Ţ{5SRaxe #9Ze%dΐ' =[k5؃+\Rrm>,$*W0#~5kիySm;u)>c̮f^e4"{Ousmz vro>~r0|Ex]wswc%Ĕ4RTy=~^#$gIe-1EݣEK(F7GmOܹ04̬" as꒜x`rsߑtJ0T>i=F*(1^d@u.:`0$d9vl9R<bVhms.%0WSSvAPsst/^bMq%I8MF>>zO;:`G.ikƊnD;HCR93y'rcX|ؒ|u=>?A/"tmjRN~AJ;_,ŤוJ3圉,aօ( RY`}tcx11:ߏ?'2ruKs/uy,1 ):ɷүE ֫7\d赹!>Iv "Ep -³O:P35>FFZv]#3/._e:'g+gЍ~_)k~E+|u|`Jp0~0s+q8breŢl[fU|qLtIHճ+U*Ii3j|sYx ˗eE8[=w<*p kP`kFVNN<5zjIxO*Tiu+S:?8dbur^2LTYHGVΉ~LPnwշ9+ŵ_.&}~Z3!EG/SBl簄UWp㱨t-}IQ! Mk)E[nl&%5 wKͦ 5k/Y28d.*cgߜwC2 fzIxgH'kȹ_J_oIDKZ')Vj2`ko 27YcPNZzXUiyD8xNPX2^]ћDQm14rXnb qԂzϷXSssd)uZ>cJQSgRwH4]-{ tfJY9Z|qn\ZBX;?.o޵'&1v}o.+xvtogsKP\GѽczV<ݮI>ZG(#N`"$0ՃR؆nt<p3`{BaT?RGy3g$*lv~+ZxBV!1?2Q+ʪ=}33}hM6ޚ=wi;^N0MLYSn'wLu˧gp'on4Z u8Hb({ 'PdX/;>'s9v% XՉ-P.#yJYF,:ZǴCS 'x 5Zi$ [j0דߘBClߐBE6=săw^yHКlr7^ FQsB HmmpU\^M2# sQU_A5Y; ۗ<3q]h F12|lO͘C6{O@Dn?L0: R1NF.}JRaxAK^Gxi0䇶Fgn9s*ȏI?ҼQ_לZ民(Sv RN6$Q؟;<*_969,(ɭ]' pbnI/}0}du/@'K--xZ(4{)LHFR/x#eFM2}|u׵QYw.if:N Z\0ƥ_Y, b'OҠJ LHu ay^)( :,1C0g=R[962J!(Ӎ)wOщh8no暼3 52+ifpSm7 ._Jr(t |կl`>ƢKnw]BMlÎ3Pj0jDp6@DRhګTn ȗg4zq Xډ$we.4c֕YQPK=af%c}lM&qSUh<1累[8`EKM }/e-ȂsR,+872R*988(aviٛ=ng' #ōFZ[msŲ:_ \'&Ѐ1LM<\`AZÔP/**1f!u.hpPt>~l}Niܹuޘ册2tl9nu7H\Yb뽡\9WB6@]| 7t9'+Ti%S_@@dR+/Ϸ*2gProUffIaH۳*VveW9p\wuy߻~~n@+wUĊIKx[H,tA|C};-{0WFǍG$o˥T]+MmDUj]$j ~kC;?sr]keyJ2fo|΁"p?3NgXB/\=Ƶ1UDpOVxBťMq>ΉWRO%twŚx>G6f>A;Oǝipy;/Q/ ]'A]\q{|FQ{S&}TxZh]& Rx?D*U.>IzH# fP][B `̼yP 6O$|n :'/,bä3˚ep Ro{x)oɛ*r5,w`Vl$5sdLjBzH43{\FVǴ 2Ė%% W.?X $ң` *n:%kL(ڸ˃7cg@&Hu649TR!H}nVmťSrg|4pBc!ᆵ 3iul~Ds"L1|zRZ~aq1?"qޮXqD ۟C4DA  $q++!:pHV|f}|:Yf*hőt#5E_8/ڡܡ"{uVXZ[_o?|%NV?&,HH.KYs=?yOL1Ve)WT*w[L.ؑSqpuԬ:N9.`jR] 6B<WMΌh~%E@z?\sih !cso?uaunDoV9 H_ Ί7JL9Q]&Nh$=[UXlFr숂 ;ɄnЬ Yu͉CHj ;X,x]J}Y-;9-fe !fԋY#+KӲ'a:YF hx7X2CQ(G0+nj1:/š5\AHWʥK+~Ƿr4^,HJ;_Q Zo3AWKשa?^̚rء S1T]qOO_g (|RO97Tg;^ 겲ՐoߨЍnOf@c4!&]ALB(mr}'w{`W >CxCx*‹IeG_=쑜VKR:Q;q4ls= ^-=^)JM?QwTflf{R q~pM@NTcYo?$w%U]dX)r3]Dl#u30!$? _.Yd=qtfbGKx ҭV|a"1~4xQCc7J$K@+)ϼEPY:>7{(4ۥd.۩(ě&z7h-A9'AQ=ۊ2ܨՈ;X´JըKۄI}=sǯXðGF04'ncqKB3>\ۋtG:/'V"B>J;戱j?tV ࠉX$ &"AN-p-WA5>%>+k6Y޷X#(Lۋtq+)szW+>2c nY/Ӱ#t® X8lA4Q„b =tJF>׍4ʂ0r Oªdʷw$a?  , Rok{PN~F ~ENɈ"r/fk,Χpc B8aC-G `d8 9V9F},Jp'ǹ!{17w)֡Cjϐ> IC$Cʆ"ٴֈKڙv63A[W.ϖE# cl?Yn3G,,ZT's$bVDnD"CK9#029m0£옚,ZgM?D4Q^0ݭy>F0RGM[?NWvwM9_׵J5&ěsSUSƼ^Ac{ RtJ3n> T{|Kn/1R7Z3w5HB2 :rg1 $z+FNl o1Q~yg|.B^Pv9"`rg~_G4P$ oBtx\_2ڨ:Tٲ;5+ cu]&<~TT"AͤOC26GR[)t,23+}S2u373kOE݀m_'[>W} IZwD+˶*LB-?Xq":1$zc.|~VD>pvO̾ˢ~uH+ }z4^& t;LH6`#1[\pPg-ۂZɂ 3ƪ@ HS0Ox{aEp^mncꨎrYuǠ9ePW*_\,OPW^1m3J@|co=fbO_۵!{x,۳,G`V8hz8)΍CT6W )kLBMkn="v#=JixrtG)de`j\H^X)6/֋:8M86uyazm ֧%k^vi(,10}+0?&|}#bo{9dؤj#Kʓ6k?64Ty,}#0_!F˄,gR x9UIUk<|,WP3o23I(fe BXM3.k@xE;b meJ*"+Ż(96av"Qz>bDz&}KQjF0:?CImXn(B#-nFjyd(J-_}iȂ33Y6AQ]?a=YMlܔB8#oTaO`nˎBXԠϊFv]Bf.A)nR|%;֒ T7:OXf5gW|N)΍au=L^#ZK*qM1orZV~|Y`K."ZoےFiyQbF&2ڦE,4 =&iٵ{sX( M{]eN7?$]{Z9ڡuS~M&Eq֢jW=? {R9 V Ï+kkxɾ@ƀ+ X. ʼ*L~~Z @)whVz@#U`Ê^7ER7-(ASv5TM;E_fh@xGo%1h9Lȣϻ=KYRJx@ [fL׏8hZw>{s v{FĴrXgVL ȁ!ya:E]c0u!tQrW|bȉ[xҠ'Esk¥)dR>LfJXBf>h<Yϵ4W =sì48s粈;5`/&c救޾ ՛Gv'g=ϫy(AXǧn_lVYhF9}FF3~k0–X.J4Pې4jυrV5^Fu7CaBs*KȪ5bU3FHE!92)PԒ-VA4ҁ/,Y5F} F/Tf`Or4 t e2ʹQ,;4RNI?3춡ҡvtC[MEz}\خS <1[@3d|B4MWtP#sKFn0q#t$ͷ7ʀ/w!Y 82ɿH 'C#҉W!%KuGi]Cŝ`Ӝ;)WgWŇ C.dFx ̶wЅQ1[&VoفpR?m3Bi+ amWفFN%QChN% x 骀#i@h!HZ*۸QWTxayo`8#93=̊r<QJMN4J=\4B&h@A߭l#>NAߟE(l߳~9*XX9FwPHQcco@V2ț70(_LYx99c#%aRQQ].ad 0<g {jv;)ћg3ԏ+!?BRJf`]y{iJ/lols $֖-wIcHWްp;e1H!YN =avq3I}vĆdZ1wul}?P%=!ث*|N"چIԁ*>H^@;ȇ?*Ϲ +Nk/?*9[RuQ! ")ļ.~k,o Ǜ /~.W~9ǎ/襁A{L#WSH2\ZGۄO= mv΋Qp?i 'ԫZ~?q;q<zN[Dܞaڞ $R_VCV#p8,/X . 縼IKĹYۗeĵZ`98!_R cY'Yǿ rEV5%Ԫ6polՑw5 l+lj傈ۇ$MM;}o[Ȟc$ Y~$+TreBc7+"옡~vOF~XS= i݈9mجx"3Jncy5-izM all]9|6q`ivDͿzoY1!k^0:h7㡩ɔx:`x|nRPti: rv:Y9&h|0tYdc#ڰq1;A~ Ԙ z \q,ҐZG5t Jyk=w Hqh%=cKoJ>PinwνQť ْYxH'EBBbipԫ&%2ʧ1gtqf>k n֒ qY*;&ރmVk pQ)GpeYTvͳ7:КN&3V'J8CB颟any#$ wMO(NWLsqD/ ~n%-ZŇ_] ًJiC.LFp:LoYu(t@8`"V-& HtZ`B`wSk|YȃukW%3vfH jqI:Udk?MJP|/.(-Yd7}l}jp]ǩD#E {1]ݞMDee;S`:NgIw:U5CQF蠜hb ۶S⡻^xBIXljFϹA).Xj✝pQ1Ec.p!tnHuYwWpR&hu(ՊrU%|W|j|eW0,=+^mK8ø2EXIi&w}$lDz-#*T&4g10@w.v8܂ʎ]thF@f5e[N`0"qdڧAf.U.ϋ6vs{Sq4v\&2hgƨrQu0%,c}Ds)k h9q~'lܐ1oOS3x@V-D酊9I _`Ǧ k"ȗƉ W݀zzXkA ;3gz-4&ī("~lŶmyIȐp4 endstream endobj 347 0 obj << /Length1 1607 /Length2 8976 /Length3 0 /Length 10013 /Filter /FlateDecode >> stream xڍPZ-Cpi,ݽFƂ A݃$x[x$̝*׶>kZCUblBiU-N~7=یFtsABvZBm28Up q qp88qXzll%F/ qqCO5#SPO:@T-@-k_%DP!vv///6Kgw6# h݁n@o5Kg_: [lpY`p @+X߳pqٿ -!.`` rTؠP%w;9disK&ܭ@.Pw6woo*y7kU6 *B-Cl1@@ / ;@ ;[`Y;>'w|^>Rl w\|K77K4gyq|9Gv60xQ>Ao$`7|FFcv@^;P܄ҰC++ء\={55k7䏮G/h k0ڰjI2/ֽ Y= FVe;,TO9!nW{qVwd.%V}[#[j='iMﵡ-MNJ PH=;·v)ѿs(Ŀ2ObnIp}U<1  {j/J) {_Mk:\$t$Fxc/})-4r>*E-)Q3:L( ]mƼFt_#kG7mu$|e18V."YaqtĿpK'@c3ʫHg^*<+vh25:ИO_)|E#{-g?]"g{ a,9Ie p[>F)?u ү]s0 .}%}nn"o z_\b޶ilPJsIɓX83#54Q!2[k*q0ԪEnjbmD\QKFBbKyvz|;ˉ"gA[uؤ0ޟdA&lvG?gOfDkwԞ3x-r_Hg(aۢ^޶,!pAaz&k~d'(kٷJ١q>3Fu)Uڼy I1#1آˬb1 $cq2MMH7G;EQyX-R*`^fqDZ^؞FˬLj8cSy%cnbu|E#6[}q)\ȒmfP`Hz'ɋ[> w/bwpJԃ\R-Lnx`y!Y1l@%dr2$%bpٛ("1x:?ыyКקK$XyB!cG\%2M?$ ሤ3SPS]<~[nUIY*'V CiN 29u1tsW5M'3i++ Z =IW'XIE?y@M3#3L?. b~kuL=tռҩܧ@Q=LKQfPBjOL+euL 3\:8iJX:WB6]8v$2v̫vK@:Wm'b09Z5.y U&Tm"JKOq¸Ek36 =&{L ϖ{~э 9^%Jö3gKW4OԼYRLEf3O'E/4] R)G-WqAA>JS땡xfrj'Ί'EV2dtqz=7Nirǥ ʐ*G 3Вgx#u>wN6_dYD *!H^K'];ੋQgC>u#Zs*B!jk.嚉{bd#L8{p':j~s+Ul1l.7{ w,#-eIZ^X@L*BJS'fd.}3yJ^@ר@L"XS1_Gp꣚W󞘷^: AvLT'/c[@gUFMTCxVO.mMM. sIU;[RxU`$A6 |fGV{oe>9ߜj+e浥+}`_IBrޤy.?@o)$cpR3>x9S|~QRbE^>MEahV`GBvjwMWoJ "<6Uu6eL4@=M5Ӈ ӯ>T Ti8R_Ɲ-mBf(:GD]8Ib.ciĂ: ZG~H$jb_慘TU(αlFD:uݓW>ve 9XRbx4];= >GDar|a8g/,K KB=4@*t~=i> FoeZ?m*Ƕ~n0͵Uѱ~H`U$iA9v6fDžZN4xC˦ZF0,ElȠjַKvt~[+ҧ/1Gl)#sן:k8qE>EkR0,6Nԝϯ#M<)T.4 `{` ebi4ͰXPMXnθy2‰,@o=Un^*8cֱzŅ ]2zuMh" !UpC=ynV*m}6XC">#,nct Jt?&Rl0y#uXcp%Jr% q\@'x9 Z4uU$D.GC׊0Oimfn-(}K"Kot 2׉^k5<";oԞ's,*>秀"Ŏ=*k*vQ i55ύb'lS:tW?g9sk0ZkBur# -<"A $&#TIuY9vd^ Fo\dS$4y[ƢU˶%CKm-WS'R?:m!%`)+'Upaٟ&|bũiP @ zo( j:ER19 =g56cnp*%tܽ*EI[I& ҢZkI\ ݬŽ&YE5lJ)4(/qM>DzP-¯'Lj3/z#C|+C\L ] Ѭ+CSG>>2懻x8 6mKdznR @6vbyZcM] ۅPpQH-DArJsJ9E:#Gvz)Qk  Az`X3HU ɷU3m,6ҵ"3-R[jcwɮq.N_~(T\ZXyA 4x"zDhXo13Be e]p)k˧Le `:)TjjB} v1W9{oՕ /db7,jԨa3V"PR͔Q/63Dȕ+ס%jbΞ8w!lQ-9rUL`R5NϺObsYl7?fŴvov0>*ɥ^Ybՙ)zg>n.D@+_ H_CXAxbt(|] țw>)~"YݾHv%9{v$[nhci8c]Tcϗs?ݴxQ&/Dj4]?ˑ$੉:Ru P o/e2_VN/EUMf%"OQEb Ń 6ulhro!1A\7STU* SIxn0,FXjs s n?8Xl_/_d5BzÙG>#Azi@CN}Z̔XL>ĕ̌AMjf儉Ƈ#jˑߵ &WN?q+ 7 SpU-a0|"7^!h,h 1IV۸S#G݈"$FY~.]3pMEN=(EX/2;kT֐ƫvNKj$:_.Szf1@OY?G"J*k5XQ_u@7&1BpoImaujF!/2SKZDck^qu]#GllR̃uU]ѲW*0+<9]d,[u DB b$&ў]e$}kϦ 8=IEcors?Fz ;MJlv5s }Eu1W4{È:{ګy5K3rG*\Ƭi(pᕇѷ戲Xx{xԫhUHtr%deTmƸcL<ȳ T0Nji$*QUy28˞pǣ:$B} ;p>MrMRZ P>O/x9uΦHK)aEM&~vV%x rtO XY{<u!VEykc'|˳|3 мQvݼ><7vfcv R [CAG"ruJZHM̑@r@8,艀Ir.fK;\Dġӥz :uTqT1^5~ #~bv1S&N hЧ \r\ TZN;?Nıŷi'& I32`4q@;u?/62ڀPza.c%4w-}fd{;`t75Lvj^Bq\Ku:Kvaha ҒLT2VGHgUޅܞ"=NnK\ncЂJltwyHL.}6ZyLa2M\&A2 !3SN>]7:BcM񄐖8{ &HCd7|X׷5*%ՌɫFNS&RjV7CjN|%& C,BP%WqӻqLGQ׽Lڄ#ڰX'˱9A&m(Fc~*!u-@dք0`=33b3b{C:U6 &ϣ^կMV O^0 J|uɎ O_oUvҰ}5(- ɽl>}hh@ЌGy\Ur25UC/.-|8 +E ߷vA` {QG6_nuBD_QW{:Ta,؈Z#*^J`U6)g@Rkv!Z71l6,?rD yORd`}C g!O#?XB^>m{`z滿Dxš},%z.XF"0S.n)}@+:dCqDiX(G2oT)L"Iv FJM+.{v(]s;|DRxmN&_  RF}S`4A;$qXvPicO:{㗽 /QWe2e^DTڮnl#x)j 7%|]>J"(A]dLhoArQ>F8K,8zk_*l(ś+ f3c @^x+ogq]掛}3X&T@ZeAGx7z%y6\ M\KD8: ɖ_"#HdK"'Q/${DS&, /{B ޓMvص`H|%oӈD=ʪqɹE"&rX?{` endstream endobj 349 0 obj << /Length1 1413 /Length2 6283 /Length3 0 /Length 7236 /Filter /FlateDecode >> stream xڍvT6%1:I(FݝRc  J" DJBBI)I%yw=ws_swLD D!1"`Q>s8 g CQHa ^ PH,K˃eA 8$# -T]@] SCyn|@~,''#;PhP 0AJ  |EQh7Ea`40/@C(hCmr@0 ^? a?py5@(tFJG@(7G]^0(&# ]~9B|Qx?q;nT1BD Eý1p_~_E @_hAbD ]H_\,p?x @2r  Jn mRzxP+ Ba@ Oÿ% tC1@g ';^ sCO ~}>Bz{b*ZBmRUE"2@q) 7C'''\+<H , M?/V_ AYo v0⿭:~3Tn^_"Ws1c{0c/3@e'ïҿKj (_;'.% ѐ ~xI @1Q$ ]QhyJ/o?1;^-4ƯojK0X GAoxua {ҀߒUvwLC."'r}AyQ_y 5YLcIIȩcR`bʻ*58N s3O7|>~4ƅ]Z5K&/(O+>Q;|t\.56i\;S\S\Z{UעŨL5i ^\W szRTS Ta]{$;ff?jb=G<V?lQx^N]vT 7z;tP20f*1vmggr|ib{If ԔJ鵤w!d_Ӗpn1U0ÖjZFI͂#FÍ,ʮL$y=S0'*9kD 56\I.@ʊa Ejq7#utO8:bԸ}` ıG:{q}0Fs½+OWx2^GU&Q$8R&6C-]s+g[8 Yu`B1@eRϪŲZt˸]]-4+o;Ͳh.Bp7<ҦT`B9^V瓊OCY4y9>v )Tm_D`>اJS>B('PަbX#%q](ܻGv8肣wc c]8vRJYm^*~咼NSBۅHg<t|RB&CWs%3箽~&v\%HX9xŦ 2]M2W"c8":#ȴqUץ&S+L67Lwg bk}_(""#"[ {&HO92}I/Nr$q>6 qE NzI:U% 6'p#p,6[ vCt4a(9DKdpDWAܚ7|^@p1vj;׵%?]fiDiRT+ÌքvR~a[K幄^i qFf!X3U0f!yi! .FmR|9!'DވG  O-=-sEK0/4߷؄fqmu̵O`$lT!Ѹo[}Ћ>w;o*XGYԵŲYc@en~j0#4{֍~ʧ6g۶,e)q{rd$_vwn+G;A+CʹF%l''!!:.Vr@eK]^媐W(d\9ˣpT.qHO)YiQzp_J5ȁ.4JqtD<(gOuTQ;w.9Z73o2~%PrQcOq*]=V9qHCХW!_6TT޶sW{N~j7J$b~rΉYF.aS]lCģvE%KD8kOl*lޕh!|N%H~xa7GxCELlyJƎۘ!TA^|z~ hE~=' g٘&3REv' T5tVv/_'*af6%xٝpT}Z gHr۾bgQ&٣xa&w3S E(r1%/Zn~aoF1~Ē\ݹQyf~F $_ 4s笰:NP}9,m|9;\/MHXJrM=m]N)Yv7~ NU7Z8_ʋ\.o\Dݷ/+ [aǜ6K y3?z߲pkkLhÜgHMObr] *g$r7՜mJy=q`+W齙 c6۸[g\FQSPNr,<3F ]޽Ș/S%:LE28cmC3_\o Hq%ϴk&LfniqI&܌flq?Zάh{g}VWF9c x::&ֈwreq0&YMk-iU:.\=8LIfv-;?t]5N?"ӫSތ4Wc! c <WEO&)?` S^}+~eP S|OUʗCB8ctbys5LJe#)EZhq'C,4ϔWϒd#Kn5 Wr7ݾ^W(+HoK"^!uc?6r8|U^ؿI^ $Qsi&lT[#OJd/r:_EDVe '4gm5\ Qk#~G SsPdޗhእ*C\}ekMaZ+ 5mNϐS/=bvIxcEv\hcyp3TǁxBسEIUvcy536+a!39̥m iS@Nqy9Svit5bFb9S %:k)z3/jPK8o)Vm7~o-ؑO6Çd~2oƿvf3`$RH)\/vz}U2u0=דW<_mì(YK$ )5D nsSq7բ`9Y}؉s }.6'5oMILd_rlM_oU]2ܣx{k<{y7X=^jM]/\} ;:/e\*E&r"FT-0kO0 y놚f{_![tY%zmA }u 7;ގԶ"Qe2qs]:pӗ%n0M$FBHχS6(fg^vjQ~0tKrљNB0y=l^FxaM( 76ra~()Ś`&iKh&Rk2v LE/ ^t SuzDqbwk6/!-U93ejzz|,xM#;mf%**ϏӦiw˽EoݲxC$f/Ol?>6+{9o+}ei+8bl6{ڧTr(Tb+2Ib,]]NU]HQ2".'.#zs;EOg\W+}v*bAI}Sŷ]/oKX_MTɧ <+~khf%62!-ؿ&j? IaQ0^5:v8o^y '!Oxl;F}촬E1J"uG1E G U[cph\4mNw.n8?7Du 0lu 1}x]pW%2ſs|#'hE{ _0~ű pYlzi1#IS2@ u>*P!Cn*L>7@zAaּ,-]cҬ;[$Avɡ\y")􃁷 l*_k5;Uwm"~\0Uq=0*vcb׵s jHY>5 mPLę錗v >> stream xڍtT]׶HtJ H3tJwwJ 030" 4HHHKt SZ߷f{}}΢oħ H>A~@IP B;-)Aîh2vӁAAa%r! #@ ؕ`p?P#  (@t{+:F02.H$\J@חC8r|!H! ;~<] ^`NH_ @+!`:FеF=8? /w?%@`pu8A=Um~$ A9ܽ`xG;nPU0D倀^^_~A_ Q "~ Aз'{nP/4 7\ k(Vs#@ P\RQ.08 q@>`  Oÿ%AA# ;CdGN# (M49Mf&h,I9o")gJa,ghF^* >gկ)mzTͶja70NK-L;\%koS,ϪD/K j~.hu|Y7Ek-VT_Wl{_s(NNux^lB33,fᱢ1'2B6Sgc 4lZ?zH\ "gJo%mڒPXQ~coH68%%fV HFђ,\tnRO$4cJ;xqLiWXLrKqL#S楑}-?A-GցM'r ECg?ݷOUL",Uj^q-,;;T5ҋ&|4ocQg"Zo$t̅~z'bK|us=y˲r3q8)>JgŚy̮uxдۂ׋[g;橛JCEt?{[Z6eh t9ps8s.?۬MjDԌǣܹ;A/B%^Bû4;rj, 6˪-kN4^ w..gWEu̧rX%"1/k]UM.zn w.rڅd`+h>5kn="ugͭa/$lJ]]GQJ/X[}9ҟ)JGaK:9;_|_^_b`L$ BY[*9/)^,3aH2)s9H2´D>>k3PN$R3u|iNiLhߔfe2]Dbr` ɮҳpLJ߿9&_7xZd\W3E nk-B9)*ٮE'<]iigoLr|)YB.r$2ȩzyјțϚ.>ӴcvJ1O][W3 䴥u)9 2<ĢD_67Nݙ泘JY)Ѱ~c@觩CN!N ~36Xq 2܆G+;MDU~-M \뢳z&~|t{)J 26T?.,KL`^Y &wb$sܴstvߪ]u.. nuÆgҧ#8dJzVHtl$f#g]g_D]('&Yx]U(gl\Aep19?OrVhɷ'`$X x'0]&W7?e0K 2v[2BCL/+<|KTbԆYD;sC~. =}BG~a0ꋹw՗ͷ])!oޘ]Ttٶi ~RCn&Nlkh4"3bD=s  X!}lϠ"ݳk ;'+#(ۃYM]Ł7}_pzpZuI~:pW{|;7F_9U 5?*?FCC깏Rka\5QT,Fồ#+v0"9\ɋmx7IE2m{o`jI/f߰, ^;d2z4ۥWsnF}|Ҍ#&$္ob!cĴY;qa54KúNaM.9dM󬓦5cNE.B0^B 1ˢBPYb&ee:tӆOǍ'fdz-<}!WZDj܊(?U<=}IqZН!7lTHj=O1m̋ꊯ 15 tn,ma;yL_`uӨ^ѓt@'zMVbL:-̴|D|Q>r~E$vr!ha|J1=O>++B?{? w[x-+恉ޮ ё܍ҏ>{q8L,=;q5'Բ,\/PVY/D9ۯJb^#>*=+EϦa1 Bu0U݋._83w)D6"ݎ|4U+FKm*' ;-1]=H'd0>"M-{~s 3P:+<:yj]y-c:FWMF59.rnDG>ޣv;}ƫUH#~v}e1Z$\5nUң+Pں\=_LSj0X/3N'S{^uf\ ? OY|`eŷ~eWDsIZNl%mGV,H;R yIk%*\ #o(KA_) )y?~2-ȫK n9Q:8* i̠!(xz4$+[>`:, Rl}ws[ v5^blHI.=UHXb%t$KHk<𝱋] 9yPC$zds䉿2w ӝTz4&N{u]ɃBr[#B:9Q+-N 'kDF_l7ÁywN0G+2K[BS]Mr~ aROY-PWCW:2?_uElh[4韔6prǜFM!l'; 7"Rz2'n=d|XUOұ~ܬLs;'= \U&3?WvZ6{Kڜ#}̙hX1IatjǃWbnΓAZ .fwA463WAΗhٺڑ{)'IWTQң" k^6i;^t,8xmE1?5 H*~|,0KĬ\D%Oq_Ӄ(${WN c?=÷i N B3olh%-J28LޭwT <`$/ Ƈrq(`9r @!1G'A!ijM,$BuGI =%a^AU*ʕjF\Ѣ\Jx3i}3DN#r4e B5iJ6,%4YUG/b6,kb槞FNI)ƥNU&I`As56qgIܝa0?׾ݜJ5z#GA4$v1QP ±rTsFŀ+]jӵ*j齞Tv&aKJXҫq|r綤!24eV MKѳi2gOg蚔&)nSYN׹ҳ'2E6 ,$]>S,I2F5:o? 2gZ0^ ģ疪Y~ K]0ezmfZGZ۲Zk?&dyp#yDK>*NZY0mI9/g䳻"KNI:Nb)* |ufhwGon7v߾A?#= .* - WA/<6(n_EvysB9d1}9!Y)Q%_8J&|\0LTiA8QO<IkL1l{|"➸m PQ'~VBHW0mNb=xq+3姡lzzLj$%FF5zUEJ9뇌@ L-%*K! lcc_>:z"#bKBe;axR?dUR_);V ˏv Uz?{WrIە?:wT[XQO2o- xs-MYF[Xr@eʯjD8r$sέ,W]&$?i'D_کn#(oz/!?\h&6pE6hrg~%?y*r\z"OvL`hmQ yj0"0Xݚe] 9$Ln <5M`f6.g߼nF/Rk>AB鹛:p"? ̰M06D(;2@sFy{d#h*1!v#}Շ3:Bݙesvۻh$!)REևh;+XWCܚu~L7tXEpMd~J==w'O=f9mjO#MkWv:J#Zp'ۑ>Kb5B݆ARW||j_tzr^Fe/MTy޶ԖSw9}4\i"-xO '.|v nn_YsR'w`ӌ/]5Y) endstream endobj 353 0 obj << /Length1 2753 /Length2 18559 /Length3 0 /Length 20113 /Filter /FlateDecode >> stream xڌuTmJ#!CIwwww7C7C#)(!ݍgwgZ\uJRe5sGS & `ffcdffET Rj]\xs2qXU f`app23Xy 7q6(0dbN^.֖V pPXxxeX8L@V@{pD3;5?.@ '^&&F{WFGKAz5 tiMcD[YHavf@W9P(9,oz`ad;v%Pgy&M\&&v&`%oQ9ȕ7Knp0s:\'n4Wދ:8z891i8X;e!YAfffnpc ^Ny|qrtX?X[_>&@ E,,sk3hi;X 7O'@<,ߟ~$%'FEE=> V66' ST?Poƃ?Cl>3] c oNnvvҠK?:vD*WU V[S xYD,o'\dfo;ʎֿ/ xl+i:J89DVN"3xX98>,5zkL wk99[o `Lb7I0IL Ib0IAl&?]G pt?] A8`RhA\4 p.Z8??3L[,L@LJ8}S3[W;W,. L]L̀v@ _bxe}N<{dO~#g7M 8ڙeşDp>vt;XO8opj./ /&c7/2^?Z|3 ^?Evp7}Z!'iOǿXXDc8,o)gK_2k?e/bw&&?nUuvsMK*= ʳs?NOb' <2p W㯅[{zIPs) |c] !.9ԅ?Ԉx0쎱rjܽ#An3B}Sĵ-#`ϻNW @"ÖG#J:_ %s/~B nڧC1w:bjaXDJpUJs4*; >>e=5bL I1;,O"\lA+jP:Tk ݫ]®$gQl @f>) ZIgXDԗn:s@nsOBR]嫉g6b,YߔEOqI2mbq6 *6 DT}|⟗Ӳ4.RT,냈ƭ^usii_u{ ^EFa U" =N/S7[7_}Ǯ|~o ב/iM~`"F*߆]TAe^DHQp '&ƍⰙTWaǺ"L^Ҵh!ĭ(L%͝+7(_d RPͺ5n g(qg\Swvf0sW D1nx[bqY;%j$]}+E|$՟«KS@L\vZRV6ur7ԭ(p-"4 (=:m=Qrnu- mm!$䯾!ҰՏR8{)ތ" ҥ浐ZuDxa@13%f]^AQVC؁쇊^zAcI>S b8j r1hgHTLʏdF &ӒkŎBM/=o#b\] -:GQ\FWލD`\73džӞ*8-rԦ8L 8S ,wlbܷTυa8b;չ٩jPTyDVw}`.. ChQYDH&EaFՏ$Iؒu ! 1/w=M0W({T+IVػJcvӒB O Q =o۱?4XMs l1;5 >>Ab;FQ;dIRkhS6½D?[>rtqχjQ*{ r+y3KSEHioW煓Q=zֵOꅌu-mXFEBYҝ$ \1-׹ Ezf;aFc\vv#6.?i\*E6T` |T8⛞)U]yؐu6cho5_݉ƴp;U#jzLXn# Zf'7 dҰ:I 2bS%CB'Ӹ9%4o%S}{ vy&fW!z,/ )gΟu׏B |20_6?4>xL%WW#Ǣ(PP%:7 yNq%R骘%$c{_h@(nzْ[H٥>K=FI< t~윸kAuiq/]< Jp<+4WR}ןR\j#$6j 'YFCeG/ hqfM*`BcqQ pQ 6ߝ ~=G3^k2o0bһ?W/F ~l|rA2&SyuJkZ1%TQ7Zfđ޼s,wYKˡuZ۲D|jlM+EwBf.}Pw)=Y}顉NzhZ=5}u9(yIa|p0rgRTQ·ibO&rn[wPG+:[- {J`FY;SVv~LY%38M^KNri*mqNEOK;Ib^K};S *f B \l\Zl P̖C%'o"ͧ$*2D#8uL.:V)t eě\M9֤Ht9i4֡':Rui Nd1n`_0" 3 ޕF!!ʭ}-ǖ<:Y!L V׏6ͤl\/LN7t!cKE}uk!k0_ }cfOJ 0:eӳo W d?~%YY " 1`4zv.2%lV5#0;k 7(#Q9kA&|T2 (ad!̝4PsS{$4ʎgie hIIGld+Tcvh9Pi{tR[H#x4Cm}`KaUՃv3lpqAILi Bk[}HnHlEZ'ԏsh>\:M=X9B?7PB 괔b[_# @*|Ň_ZH_ TN!#IUL$H}ֽ ^.C1j1vY:ٱLk!Ve׬lDH3c ":v3MnA!@Ԙ[ܗTHTQM0V6@bXsH4gkBVwm.裫[ܬ1ز;*f9tΚ w؀}aVzEX-kcsP:f17 曗[%4pn K OxzF/M\Xsuz ׿rp,s+2| qZF'/foIQܧ_>4ؽv3vݫO2ݚ}E lZZxKnĢn!ȎI7%J-StEqn~q-_UN.Oۗb\q׻W{@nѧվqW8"w'^Ų~#3;d pxʉsS„hsyϳpUGǒũڙx8|13"Ơ[}rDGp.`/t-bQXA\L 1pM#2)"&fT쒯]ZMK8; 0>$5"A0qnRk, }ܥsW•1q:D" S Svrȝ %QF?7ԆF/"Z{͕YݤW_Dz^:&W"Y\x Ws(#ռw [z}=c NWӿ!aY9 Dqd鳢ؾQz`yԠ镥PT, A}W]q_j3)bW#C*j7ϔʌz s>E=Lܰ-lb1哦-m(lC^a,b{N&F&jc`cJDFz8OARAR}ZSM:Y=fx\nV7h"q)G@1CDF$EĹ͵wv)b3ظu5=kܹ,PiU/0\.n&wIWnGӭ4#@=Dr#y>YB u?5S0 ^&Fj/vgJ蚹0vNd ` ơPhV"h?76> m(jHUŨjE=D| КHqplڽL=){KU<>ܒ?__Df 0t%o1 ~V!P X°߅ 2jy~BcM,̨kCøZfIsv^2A*TEAɱbW=Bqã$ϫ6W-DEzsyBj4BUtmHSogK"<٩(9Y)SqtF8Rٖ&o:jDAJ-hq ۝sNbs/v.Dzf̧e* T^o6c8(}Ux:^>~䪾QasETF; 1CNZٌHMmD{Gtru|Fv/"]sf~^Hf0Wcω7gŵ)E>RO "hJFX~JzɀmA`(xoцDZPex$niOr5RAAFWtqψWo 198xu#<]}{ȝ uNV>giZ_6wI/}&2ʥ hhe=+K_9$gj<78hn~야k?Gپ\8Q7vɂW*l.ŤVyb-dBKF%L̸ۇ6`~#/SǀCs-O/plm|:PH~+Ki=IAW-6s*Ctˑ$[f:2i(ZM9wA+FܳRoK޶&LkXmUkegd@yfH¯dYMds5e^|J!-|Ͻ#KuBk:qm./ 5> |Z_˂74du`$U?E)5_c0913H{;[9+̯n(&7vqy] SZ|&"Uz1vG#Et%["?ϐt8E-Q5};G:|va%<:w^_5V<7f Űz/} ~X 7tzG>OINeÀDaW/CxK7 bh]o|鼰 ܠ * u~4y}3-*^Q6$d.vt/py}O\ bVz["i?,7ml?u*P?*c8mzM~aeӿ;C/jiMrȃ1VD>zɴp賵J*k]5~vVluW#!y\)e2 )!_#كt@CuG"*y",M}#_w1g;1 RfԚ<ݪud^mTՙn 4ޟHK=l%ϩ$CR{W9u :{#QS+ ԯe]Xi}D?j(*vO@}"ԧz ҫsGS{k㉼34ZjO֨I ruŇ#2+wI DIWZa/;]+= VdvΪ+ʪ2Y\3ԅ,y=h؜VvHAn|ښV8?<̡UApOOhNId<@M]'ٲabB#{T ;naJ]rZYƫ=%ub4m7g5SaPB=d?rهR<ڸ^[,8qmII@/9ݵ;;Ɔy-eA*bZJ.+S uS|=~jdݡ$Yns{/y#wӲBsD]?"_jEzY* o c _r)V".;Yߙtk mz)p׎!/:6֧ K)}v5N߬( %w؍%Vݾ;j ϟJ;&&Ac{c#b➢Q<-0i(9Rr PZ|TeVE1 &;/W}ԛa) W0:_Z!9 oT.'s'zXgePxJIQa&q/OX@lHs 6z) DKG}U'Č'yh|A]HCD?˸uAn*Uġn"ruTp6o^{m &^+Y#z=y32MjFک5l3ʳ<)XǂŃWʅH\"]uY\h-3InMqNPrs5^7L:`p/gv}׬WYOW gV#WO[|Q0&xI B{v2 e0 lPD2߀ϭxY\bQj/)>,gC;>崯pkGU: \ [[o )Z$`Ѫu͡D{SIMƚ;ƽ3bnO (hOL5+A-qz:X6z4bws_T_'.\D>Tx:bJnXɋ%čCX6sކnnZ%z>!G,aRo1^~LJ-(ݦ\{J"#0fvLKzI$f A S2 c Xg<4E ԭNeM :wBc~oǗ^N)JA3AF8Q&s(Q!T7^?=X r$cRgZc(PJŞYӾut XɵygX( k@Wig5]dMz*xpʩ'6# n:RN&%x.ѐM0 Jzsdzb9buG9螧x|m$hk3H;]"ӘbvU!vzFHJ1- .Mj1*B]^R8!3y-hGF;>qǯ08ֿeت:# wP,"NT4c Ryj!N e]";O!̝"l*7z|Yx^OPRt蝋.O/c P Nc(u};%U[!_s뺙VΛO|,yZꋼˌZQ `g+5j E^pѲ"y F\1)V`͒Jڥ Y@VIr?<%i[ g*y=4ٶܐQz8ya% )`\*a߻ɳUߙ}EB6;wytBΝL[ΗgMB#vӛ;bs{f,/暹/<&GMx'@FRۿ¨c %a1#/aUu708e'IUx-0QP2s$ĻqV OuCF,8zApdL2?"bk}3'=6c:PU;O0~*~h>~*ai<:9'z}˞Ϳ|phQ >湀yH߲*ՌqO1a뾼F¾~88oN5)I.NXQ5Y0[5 H:f;)w̡Rgˀ$c]|6Xo<1ph:|Nxo@^ƪ%f(kyO.tLZzܳ-cb/Z :/;ҲOѰF A|'B$g] k(%)^Zv 2bX-MrsJAA|Cx4k&1F}r^q UjY'"!ƳKNOѲ(֙ġJ7U IJ9Pw D 90=Lx({9]]@x* GfDjb׳jH%v~A' Ff1z~NXYl6jS͝r|J$"iczkٴfc,ا\@ϞYLp q`bK흻S b(s`'ap9u靍8#4]w゗f]>6Ν8izDֶLM{b I5a><~~BW;{Q#;wͣuBE;\,|E "toD @aWƤa\U+&5jraP@o8ڣOjg/0⒡*]\ʯ0N 'gkAKonsd^Ӌ;/"y}IuwAU rͨRown L3o9#4 t -|_Kbl>L^dl^_z]7uCWL4|e E4GTs%Li3;NeH oTkZ74>묄:8k;̊yDHTYb,d( \vzK67-jaݫA -{TgVΖ}26|~# bƅ>v.ڄv`_+)D[ʍS4 y7[Ɍp;3$8-x Pѝ\I.og#fni{[ɥGrB)d{ʎYM Pڟ-5 V"ˤ(_,[W^G߈=Gx>DI3x 8"^(]=GuA STVʼn' srB8M+'HZwļ ߏM qHŭaEtakoXbȠf6@Ye ݱzQ@KNrΗ(hmC[@!$UgNm;-,kXrmaWSgjiј'3i4ɴH'_t7]#6 2'/"6#͒^D0T}_γءU87s{ԩx y8YқXq^byƦ$i.\Y\CZ϶ׅ-IOsP;^cCmjAIȥcOZUIrB/ӕSc3\0wȖjsVPSfYw5^71r>*?9,}e~l]Xkm: "vq:b5u~YUOE3/;]},wNI'XwPHB-&EDI ՚6P fGFv~X79S/3j;^ s@mCկ>_T>$~P!Rr+DlTjy0Ӡw'·ύmz>ꀎOIPJ#{*[MB$޶]*cJlq7Qu/V!PHCD1dDEypzjEf}|7f {tc:R]8m|!2!MN]UW GK+T=yŝ3KC.q_9XxR3JgaJl<+'7kKGzF0Pg*h#naSB%f}R 1]wƵ Ų$QD,>ΧwfIò#~ HA&t=M5|؅yăδ4'dQڵGg64\"+>鉅x$Iܱ][s a;|Ïܪ!^!m雵AZ-ka΢@F&[/): iN:|Z[o#2>o\H⇣25(,;ɦU4$$$ itЈc|!zo9`%s.9LbC>tx43y\'AxxA@y ϴC'b75b/v`â0\&o_gz9a`$uaA㈤T0tW{R\>S JgriWDy`z,_,61~'YDpKEJeG'fAMpQ*厏 z2dTpuJyuCVr p) ;!JBkߛWыcq dB%O']ǺjYفV)8b˳s7X +4?aGY6͋OFp# pSF?Rwy>JE}yc.m"2@VxcE Â8Mq.lV$#dG0-Y7V#64R'#K-m j#USP3{ڍ:oˤ$tՙ{)@[o6^cŗQa#*SԪ 9EI6] p"c!VкO@Qq"ґVgJR%t=.)'q6nw߼!:%\H#Z51(RZDTAu3c?R <29~>F b"RT[|6qޔQhr$ IȨ]J[jӮQUǽv.h*)#ȞzۗOh^跕jň٫0U<hrMv>}Q !6zSw43xqOC>4E|Ί 5^eW-(tJY%@ ˱g{q$|qAbe*H6bxeƤB%1Kg|,wiaRK6V9Me;Ei`W"YgCAtu)w$3Fpt1*xHR0Q˗Ð Ť;MPk2AS/>yq|,΀䬺'zrm(VLMkn+!W>H5.dlPiX׽ZQG|]:B}05'W'  #N'~tm1$~6tuU@iXB{_/̛l.K;PCp692h Wԯ>Qbi |8 N2\~Ifc|r;haB8sGT![r1lE5J/j7މ$͌A Hp#@oJ3|uRĵfv 6w,6LTZ⺛s.׿%ߣ7}WphT\u4U|]k ƂD bc*逹 հkG,\S;hcٔ@MG`mQPjfQak ;2?5R+kvt/ =U ^>NDӋ5f0D,FP/W71EJ}g{>s#]ѻPegk$ҹsy>NR|[-X6is69V|:e߽K7ulJ*r)Ġd@Bͷ6 ͷ&^=kb~"91ϣ*Pw&XJAɌOj6W-6>C1+ ?w=s?զf(!FFy_%9%j`8Īд"҃; -Ιo)1>   PAf5oy7NuFD }+GVDg"XuFE>]Ih)mf\\iegcC\vmA{[a^QnQ-Cl`z75#7f<$3ۺ$פwiX-r׎ϟTyj‡'(υtt0 V_2H~@_q7gEiʥ/"Ǥ <- ,]x7v "4"EU~i]١>%M<_OE{YM" .;lu >KQһ1y؞U LWT=ɸ((=>m-sÆ"_6q'IjNU񇰳Ub_ҕBP0@E bAb,ƙvĚ:!hPOeHh6[F 6Wbc˩}[!$F﫬PZNn Vv2~V\=9.)\*G@iW::qd&[S7>K7nFcH8mxM(Aa^2N6"pE/uΚ{lčZbD&_(K@K@ uqFk2ߦ;"Mz+s.,)e/7ǡy$Z?kxqU٥=8 >bƬFI.tlG aC\[*;7O'0FKYlJgYT\c4t'iIz;W:VqXC]Kozv#^D-Xe5-3_HjV9ӶޞE:# #\Y0k BҨ /IJ]b`D<=ױȞmG&v?Wo/<\yNw1[Q00*4,5l*wՍR[s8exwKzazpV-+?k!GdQȔL}NzPQf\%/l$^Eͳr XDn<֫k7(]-l+ls%SJ:~Ŋij`iRJAu=C=W>^FtEGXM`,87/.@YYR[:+%[^AckHCڼntC{SBHtzaM &Sb$X+bJ^PTh@G$V(¶nOmw5Usݛ_{瓴X怇= )XӋ1)뮣;"}iza3z5pw6Ik)u%)w]8g*ITD%2UVh͕FY8 yfH.~N]^5Ƿтϊ,] 4 -/u2 ΂48|jY=[Rr˳Dlͅ @t\ְǚ@?wU&S 6;i S pJhNu@8ޢթ\+wieͷ5L'`(J*I_Ct D"JSyL!sݟp\ q@VUj(ٽsت؅u0 #-8Ahcp2vb)i։\$Js#$dD@[$!.1p@:m_z$U46>zI 2E_rۧe0̻ PFM;ݟR6|4:?Y\oމc3a1WmԷP@d $;+7\=iOa)g :"(^5L5)PẺa4߁̶{ʺ4idZ>~.\p9; ?'s+.F`mo ݘ&FTd8YT~:UF=THgtEjT7΢`)/WcĔwaD ]ZC"QnXu"sCa7@ۗt&3!rX]Hub {~W HAcЮp $2 rϜ>dTgcyϕA칭B%YMW#uL,g;Qi Y^,l#5kY;+~s{XGUz|gWK[Sy99N{<3/ƒ镸.Ƚ*EyQ=dx!05 h&25$aM<(QGN}t!ojzdԚIc`n$pu}3[Tfw9 cMzd0r a]#{.}-̨4\V[seQzשMVյH'p@3{U.^Sv ;ծ[JfDu#Rm2N#;>KWܩW&! mnBk !4ewMhi1 endstream endobj 355 0 obj << /Length1 1473 /Length2 6717 /Length3 0 /Length 7708 /Filter /FlateDecode >> stream xڍTk6Lt#Ht3tw)% 3C#H+]JJHtH4RJK7zPG?@#ٔO3 G@PRRw:@ ut `wTG;7! W NBJ@חtB 0v еsƏ0@ N^v`uÐo#0i`_`?O?ٿ Aa;? pzj^~^;/ʷ󱃺٣G)P C:xB^H~$G_ePǬ sTa^H_@=ss0/,o stE!` zxA*0(?>g@JIDW#wP!(GP4AP'0?ixyz;o _Pu؃0`l{B@__Ôe. cg;'7c/wn\M_eJQ6b;ٯ>'Ej{ mjut |=Q8ܘz. ѸO1{WBB#ME[kʼnv+Ha[*Efj\/:t%BŎ\V8`m[UgIkD(=rP歁A"vcǖuPRBCX'kaʹEh~;W(DF9jݧs;h>Bp2_4"yCy5FUdE [^r0(ux뽸y'}-zG Cob\hOj0%:,r"bDJ/P e!=?mƛAQC暡[2$@beJ{~ݞS`ѶP$f!p]~Lf$"@CEzs }s cc78RïpW{Hq|.܏~\7gK0bGQX2q,G6/Ty4pAMi ˖kC?fƶFaZ4c4 CUSHٚ8.G5<$їpB3Zaj2܍jk6<ػ%O/f=u*&/\X@Qʿ-#h5[Rk6Ӡ_Uc7gCb2h,+ivS{ & |甿ո"̴H ;u>Imk$xa|]~œoJ7Aݝe@!x݌($8|gP|ϻeY~| x [H ;kw)&^YŚ`Zh7;_yA vM|MMSv67U+tzAiAtQM:1N6CTИ_FbEIJEY)&Fl_6UC e) ]냽+F!MX 8134.rN"ր`& MKF:'ia7_f=$;ԨP6RvveZX^3g4?¯cʟj2Q43{c'2&caMоnI#C-ѰG:V!x nj;]/&`Y 嬂jXle|B܇0uc^:G#@y6nVT wKﮇt25}SC [?/t,KOFi ݒL<ݸ' [XnJFDl ݕ!4*}'iURyD)o2>όATa=ei{3'G?7uNa7wDw4gL=O{}N̥#/TiAK(l2F4+V\ƒb؄;YPH+Mj- K!U-ctH&e{\:5\ò yyϙltTtnhnp"ZMEl(qyL^n^V42F]x 8Z@Ǜc>ܓhJG~2Ԅ-qeOZ$[1pE8DL4SN4HԳ}F+i(wAkT`l.&35ҥ;_sj͛,xrOdYK="~wM$Pl81(Z\i18Qynb6ByTw$w)>*:sEIH_sP1лkh^ίO_ҴEu H'rM( ն|Щi.o@hua.Qgv繛6q50jrXtK̊7q'9_RI"E8:b;CkuP+Iji:pcgm׋*bhDӺ6.kfϝO/?zP<†H>g~Z2{Ni~@$1 >e̳Sn]PS!z9QX\頰ZOD2 Ş:|w'?A ң>tFdBij$CFl]IRdN3TǢZ}wS]lz{TI#g2{ء=2i/KؒaΆ7fM#•+#jmcV`HAS0hJ9d.#U0[ׁlڌ 8Bmu3`l3,Z h[xMY Z_1 S&LRp'"ef{lJj@'4YtKT-nSU>_qfl/yiy2>%*:XDgdC/@\(GD+21y9xؙ x]nb^RfE9L;wh$:ZtSdCK)gFq*S,d z{YM73w9?·Ћ*R&W>~wy}|N353sŞRQĀR=Öy;tx򚜟% xڇ%2d-2iӷAmo "%_̝WkzX/cZjKDZΨƧϵ%M/YT{w e>Q^4kLwS>6׆^oE]|im_?iYOW[ѕm@crϜ WOHeiv"|ϼboڟw"PpDOO wSE d",:^:cW?-nG^H- N~ b=`^y)zt4>34S-.7c)2[ kZ/[ؐ@5Z"Te+SGtf*Yc`g;ϙw%C> n=Y ];8Nr$c y"dCSo56K;[@y%:IU^͐7ϊ 2J؊)nFxM*;aWPʳ2[(yhS(y3Ftz΄80GH6 ?\CO~F^&T^@j892R kjR##gE&C܄NbZ80c"uƧ 2"Z5qcd6Y&/GR~^&'9! KM-'yLxa$?_R#vO|tj^WɍuP$uCnI*SquZש}-nR6.P^8w,94q/tLu#Aء;!'4To%.k_ub*Dԕp`ǠG4xzm'ϝ Er|h䈱0 6nNz$t[TmKXeg1S9˰Vi59p#Lb;#o`%3yhb2ܶ<>&>/!7cXHfH()m侱7j0rA[oςb䴟 $ orZݵuVu5peW'\ǝ"zUb&rI#0NsWMbKʔ6v7a{rv߯tSVOW_"0we6BY6l~*QBG 8sws!u#1MUWC \ _C$OQs%q";rzgTZi槴y>U'e~)J=Å.^9̋WŦ|e3>G$-ջZ(坉Oy/qsP @@W8YђZ޽^ͷΪ9CėYn†vnj?/N"˺՚Thăٔ<"*Ucw>hoOXopH w"gH' Z8TP3Ƅe$=YR.r$*kw>",Ƿ"2zȫn JnjF!_,o,aƖi3tEa&a||Zm#pWŒ57Ptw [̱q(:z4wWI'AQ X#<;;S+w_r߽(E ~4h@ꃹ1˜8?L5jv}= 5,+}DSIVh먋= Tux+0r#0ևl5ٲ)yJoW 5f&"υf1p߷Jۀ endstream endobj 357 0 obj << /Length1 1465 /Length2 8139 /Length3 0 /Length 9122 /Filter /FlateDecode >> stream xڍTl-L ! CwK0H 00tH4") " JIIu}]̜s<<, <5TJ@ ~ pXX@0?3(w" F@- @ /@?@8B xp;"G/݆/..' El.-0|ЇH*.eDJyyyy;n iЃCP7e675^W@n#{~"jW_`Ϳ܀rg.s ;]|`.v[ɋFr.@;> 9F n"yaN9.sJ.E3{'0}\G?-bÕU{7ޅo bmc'}!  BpP [8 \p] ˾` ? ]| s|ZOUԹ# DE]_ǫ =Sspv[/ ;h [f@a IS*WDNN?q3oĽ=BZg-(Q5$~C]u0we7 CQ?p_ Յ~7~ b+gx_֟~ {E`ח0~G!P?){v[8X@Aݿ{q)C) cׄ6^ (j37 w x^ƋgcTze0oqI*+tq*jhq]Dno+CӖ+kD/}c{򵽏iy@r7nBћQY<t {x- Gn<ݬ.51 )fɷΞdD<~IrM8}r:E;vGȅ+dE bwHʄ1 v:ge9@^^zvj$@'Ĝ0s@K-_Q7vֆ+ggJ.[//eH(D3KosuxDc{͘6bғHR-L_b~cSޛ}J?<p _e=*| 2xRH J۬tj^`hV{IƕmSX5I#MwwhɢeLr J}ȭN˲+1Wt^4ƴIv$81͐6Z4ZUؘo~]ʤp0?7Fi(k^n)~7TBJ{WG(mӊ,r*.Y; Z# RSMwJv'ϙg L643_SY)ĐiJ&+IƇIFqږmY^˛ؼ!U%X>))NoM4aE|^ƣw ~'"r[;ْ|Umcz_kL;g9Z,.S\GXpxCtP8.f~&c@0AY#P<⭨9HT~QJG W2n)!Fu aT#PtCklt٣O- jVץyO[c63B^ƭݩs6>"'SeʈnZ{{k }1MS(kxNuتk-jov^ kix{BA)(O:ЭC$ ̃`}^-VwۅX1l]V+]x PZ ӷ֑㸳<+K:רevircyJu.pXXi)5z%xa#ު<<ה-6>\GS Ysf^rNU=$]v93Q9~1BzV+W4 =5dC`;|GM0Xe=Oz]k,/~(ȟ8brj3W C3aһ}09C%U/u_cwԱt:o}?uQ{#J<%d sV@ p08xjno8yn??TWlk}2_% A6  #?]^}Z~eNDcw~W p|;_ƬmU6s(_F b WLP J.Ui~%>{duqpQ0,|?/Vt i4CkAPt܉+NTz$ ˬXFB WwRgي~'atѯmbte(y<݁MVAQK57ӎ9GIJ~0i=dE mvFQH#] 3Fc^o~+*{W%~7O($JG}vy$#wpeWp3L$X~bEꝺAc-%8J n˸Y;";:'Gs7ʻU$]]Gctv$E$o}mӌ DKx)Yyrox2l~%Rz@uNZanV]UĔ]!+vŊMaAGL} F[F YYڭQ1k^[ҧ=\݈ #Y{1a2>0mij2`T!QK%շY1*Pja&*u&T E}_W *y<݆7K,K޳.yQ g]gӷdX aEtlbS7[? Շ^H]045*D5~Ҷ 'a,/ H..LETm_W*#A_r]!$lc`C !J."aeiu:eEjXj#Kӣ1jsw)buWbhVy)]شrrQӫ vKfQ1> _bߖ&uDT}yb]ka{e }ZE[-7sBsźJ,l@AO\D'=#FEtvxA&3́-ìaL^X3^{J@_ PO3dm'k74aWیt w3|NmԻS Q`Ф\*S/QL{#ZIuEnRc?.;U:pábD Q \zKlHS9я&Lg !j-fVnh}ز_wK{}Sv?H2ai^FqMɧc:¤ AɅ +{VQQ$ݾN ?N3 w_a~#O;F0%͕a]Q]5׋')`m p 9 H[YZgʖg0i-,a(Y[=Fi]ڝ{Q/_/H*UTigW'wl0c=+zGXEpRCs?+9! <lgD ~` #JǬ QQchdvE-ӷFE\|YuK|u9ۀpo9ioa ͫòL)ֲݹ[o{9ѯZ_k8Glj-kʎ28p^Op4˓|x<(Xk)aUOQuF<EԐT`IjAD_UcSC/9;w,Y֦:Gdz^͟*2nKTEK1Bc3Dok\r{*E2Z# z2݄.v:DfP4ٺ#bC>jEkK,Jv$f|nX'@e(bP&iןDW5p[Px'tc3Q8#@,rJh)RFQ0T"Jc06AۊJgP\YtZ;1ffd]O_; CK?Ȗ?c{uqcGm |Ee p=sT_rMkgtjBfW-bb5[(,ujϙcvq 6- Ĩ\%dʆ.1=c k] [6vZ&7ڒڰIۼ@*]2_Fsޥ9)=jEObr,&]\"L{%Qp&n/QPtO_<alUenPBg_ڮ #@y_.v僪\65u 2P[z AEIAOF ZyYqHpePKt)k榋GvQ[g+\ϭwK :m&KIez-6-A9J">JY˜elLg/07L욝yD!> -THj4|l8З S|^-<'@E>9LN&5x?ey8uŃڲk|?ƣ=T츙>ih (EQ/DxSD#'Wϫv;Ed"i%Aޘl;2Er&eDx~Svv<%C\FI۷Et<}-3x c]= . Vͷn7fف[B/jnQh~V!dυG'6#sL_ECwBw0\H)Zvq?K ~WiN\_!ՠƋߋ KꜽTAX8}kH".AٿS"[gI7ChrیE|I]yAfo+,c߫z寲>h{?| >@εUTFx%x܀8q5.`'Y##TT%j [/>%WM~SZWY|2 7Vnk|i!i;lZ@oEĮTDI߅+))b;{T`1GJt^X]=J:B*_/<ÍⲸwo$ml&Xx*6:rhIm#.vIAy[ד'zB8,:D֫IHdӷvO95kz`,gvzPH mc\OL[Ml8 \苛 D 1,պ؍UqKx(H7LAs8rNQHa⼧:_o&LlEۙ#F/ dҙ,:/||TF.rJcswǝD)BZVڍwd)rv0HZ_Mӵ"NO3jNXV# &w2?ǩJAxu~)тh\aF~@}|Cƨ)fzԭH8c#[]fNq =$Z$MWŏ8 IqD'dz~Ov2Cq˝P KLXFϵt8[ک]he+N#شnhY%dK%)A"Q cdžIxSHTSJ>JqFQ-3 _?q/XRZڇJ$ nAzuUOVt-F9U# ,?gj繚 +%8.%~QyK3 ChV5Yߴu3W/٢bRG(XyRLac\*\R8 x_t΍.ܣFy#$p C|+Z VgT[S:M;,9عݵLO~W ΂%\fPy^?fV 6;!fbMCMh/9F< XgyeKݝeX|iAuX[|3}hP7 <5-]& gbdU6oe Q^*yk05b^|"|wnZOȯqsz(}R+9aE+*wSJԷy8ZmD|)4oe'9$.nw,*΂lm d+ 9/;?b|p-^5ƇCUYjv{2+0E߂\,m( y::#+)4c g(t⪊͟+Nnyİ(r-mѫWrK!Ye{G{=eXN:8 Vf|ݑ5y6۰^r~:* }YVkx@)`03~mOf>!u~9^8Swf4cZv;l`=yP: EYq,$OK]%(OqPf u0en=$n*Nю| {c?){LxCQq-ᒭki{uHЛP)Ns 0 -+ L< T;YL]ķsffmpt6d}DYIq^%jFh/a;ZëKho~XK4~%`lЂɛ̛>ؗk!ͣژ؈fP)Pp(+a<0v!fL>,ΙRLi$Y1E92Y(R*΍9{+2,z$) >1/ՔM]3y^9qrKºD}]uԤ,m'HK1S|?ڹ&YTFZ2m/\ʸf2?d.:d.p/05s??9R=ѕ?{7$  BWvW$,)SnfYЮ endstream endobj 359 0 obj << /Length1 2394 /Length2 10122 /Length3 0 /Length 11505 /Filter /FlateDecode >> stream xڍTk6L7"ݲ[6MAD;S$%IZ߷XKf{fgGZ,N`Y'G7VvA6'F;.j(C Am@7(Qnp r 8Ct6V#Fbce? _` PYA@{_!腭ܜ<==YN+Qf5@ x-%Tm\vh9Yy!``o;B;Z!hv2@7Yo38X9 ߁l: 6VK{0@MVˍtMڻ:A=6@s(ҁY } +ol@,h!vtsE]  ݛ˵sttq-ݙM jB{Y<\\ f@` C=7;O#4 `qD{5-xء`_& pr~ulڊ*LH))eprqx8<h˪6x N%@{?K Ni蟆ߘy:7_+uO7:{ÀNt3TT=qw_!V6U lnkbs 6`u'W |ЕAWeC738,~'/ء::ANW`m$M ؤM_`}B6' `B\6' `S|BOO Aԟ4fzB OV A=!h>|R t{rBO*ف?X\ނP-4:ps88<=lB.h,큐?*OF.}z"@dVgć:~aTw`?PZC? TS=PE'mH}JٜЂjr7n~nhЧpn<]Z0P-6I7@W?O@D67k{Ph ? @h< '_;#^yק о:mk[%H=Y81#/Pd=v5pFKtLD]r~xl'`3]}.J[] & CWewvC3.G +& )Bf홬}9aڦ_֧t Gpc1QD\pY5Sm ԮcIz9y6ʘamߑ`:+]du(Mhdn/Z]G㋹I,( Mǵ[97]hk3Z%lb-(KT~ހp6īӷȄOY,Fe*~FblvNgˏ#XsDnSxvqRP~~3&Y<[QSwch=vA:)E|6CuS!ؑ^DcdG)ٳ.Jt5OW‘Ux==$S5~,3:”+ÍNX<+ Zn 58ET쳔rɭc(j1f^ݗ $5͊O_*c7doTgW-ZrS,،ݷ3^vbgd44O9I}VPu{lv^"%h.d$huM|Dr2K+`G6V9.C~S0y(G;'S'K/ka˜^X%җvyX@;"E _yvܻ`Lѿ-ћF8ܖŒvUPwU2]Q+&M>E622VK쾲cB9d6VZK!dEZו%`q8o2v `rT깵EXgr.|0w A~X GE欦]ƛ_Ǘ5߯0ʍx/jV`RdjXh ޚlM8+urg_ <8xԺ屺p=y4nOd$ ;~pUf}zVj )W[g)"5U6vN4PK0YelAej]Oz[ϑH9+H()I#~|LdvX"宋Ųfjˢ 8,>oH@+}> ؓܡ]K:T9C"}5ͷm@gErP3!Ǜ(h?t 7\!K:wӺxԇ.>ft¯^b =S#Ac>J(N~^mg=!AOUf[4M4NO Z[3srͤ7ܧl{|ҁn> mcNje:mg' iTypYȞr'Ӧ(c Ktc""F ,~JFJfWpݹzI:_s1V"T^ܚp|.^OjzW}Vޞ`B#Y6Qe%ևN@zG~B.Կu FL~N>K##Au#˄vY|G\);Y(g* 5ň&b6l0XZg2ęgjwN,,'WgiN*xVIè;&fenNhaI<%Qʒsѝs x%Sx{_yvpɗ*Y]~/G@5q6: ch!*pyt~Wx U|̺nFyA6syDGLjQ޷@8zq=tb'KBٕyrMl8NS^)mi|c2gʛԥIUNkͥlqJ:#r@E{s ?"sEceϦ/5!D%u*Q2|#N:7U):yjp!bhϞ|#/}9B)`Ϛk$ E]_F,daC5 NdӴn!.xMUy>LЖ(e;okAU+kTirV1 AO=lP+Jq3ER ngGZ!KwS7@@l4u'OJEq5&u܎t›5YOj\$r)N֏gy#<ݎ|5+?i~ 6V-i9J.^F͙?fs%kW{e0l% 6v=,U~'}*"RT-C"dӡomߙ']SxG29>d1"*!˶3<˷?TJNO4ZW&͆1/K,V&mM^ڲo"9G谨$^D4`4 c4 '7&֓V”֑];ZLǘmJ֒EjTgj]tq_/_`XYMgs|>$v^Gix8Ar .݂y\=A~e"n- E>c j4DV'QX"Sk!<+1-&iIϭe#Hf7(}9v[9'9ՁPqa9OW>[2r]'w!4 ҆X7&%RYxtj'0eBs"F »PyKݗ}ɢ ?t#o 39菜>$7OtܶCd2%5$6m}vb嚒$sgfP$%iɉl8ի) Q,۵z H{ /mpvP I-5*BXY?3{`އ od|5.M|ylCZmC@|Sb"k6'y H&AJWUy ){mt {ѨJRv į{K"A-khxԺG=k}VJ*hJ'.QGYтI}+[(Uö\:Z{[&Pz}pNgBi:t'_ʤre` x!ԤII6rp&$')c怇vl/ XhoDȅlȱE ƚÃķ1 G6peXCSp&*_"5;vӭif="y[o}G@*fĕfM, h/$]_5 h p!,`$u{G:Xtn\`AkCy!t (YՎs{S?d÷ |*#'tUZT~DiÙ_^-CFSތ[&׆l2}"(2!_ǽd gqPD)Xo\L.Hߝ^0cy-s!LY?f,I>>$K|C%$LcAM Yz91Bgxͨ |2D4]MMwP%$_Wkr8l:bi}1 ե$k5mVvdin_K0VX\Y\GGSb"ݹlX!0<$Ch[-fad|G`XliouWp {@/$݈j_+6$~ d>Gb )N_#:r2fR{m 0=_y/=}.9iRzL«Nwf_d_GjȀF” FLˑT;ůV^!ᙝPxt:C H##)l>H:s[{/+Km_I.ubWcj9"]OMعRxZ;9=:j(}$Ufɑu_œDQqW]?-+2;1;@<ƚ$<}yvH^vfbW;`z_bx3| b:ݗgj3su_|RE N^>]41XbZAH@rv5ʺ7ki( fX>5uPU&=H$h0qK_?1qqXU]3VS*ZJw\t3l]c1)׽Hb!6#^by8ͣT^5I5V]=Blxfse+c>MPxZyY&軹 Rhle-v{Ǻf13Eomd* ^[J)!yu1^XO tVޅbWɥ{o%&beAbӐdL\:7%>DP1|Pl{mH%8g,\~(^s:o*0aT"%KL!qI(QU>X\r+'wa6 4P1+0&9^GZ{u7RI(Χ>qelPᇗ1*n w>!q WY|t+VOʊi.}|󼝑S ݤs^?cla!2l["汯d_VN}ˋP E儛 5( ϟمk5ށ]KMY@DB¿s,XXۮKzڛo=xe8(Xpw%zD鯤$"EƖ"7љ5'Uok]|E`yfw /dEG=:?ͭ,Ko2q.]xh*fccVdGh|YMa~euEm|lcI.e#JQgTOnζb8N-럤5iHRvk&J,~xT6p/ǑJ|[JZкy_x3Hc欲ǪC*2Q|nŷ'q렩KkZy;cs$ O$Sb YS79(225pK# r&nT@)3U>X._ν9+Lrw?xrH# r aiW {?foFJUwvb,NZJDW=q\6j-6ᣦR&X-忺_샮0?7SD2!A p]~|u#f}5@Z_u@nd;*;/Oj"ѯ vnH7ю(wѭWpZol{1kL1O,+}tT 5ĺưګH8N$Q؋ Sho5Y6fTlՇxL~ڬ ӂՁgo'INɾ!}]nNxԉ>~ce 晤mdMoOL{gl}6w#Xk" O?)!x]БG,b-'8N;֢ &QȐ /e)O {B5`Vzg\ix*CrAXͮ$Cvf#~;qu}RhTB3 ;fgSz|уE;"b=_%D:,04 kk4HJ5Y:{|wV鱙V\C ㉦D28peoVL}PωNF;'$ ͏i,r~/8{+ MV@z%NÎG=:-Հik w-D$) U (~!4gt&[8#%jϊ0EZP.oUv5O8D}YЦiJǟ/ )?T_ J)2/Ex }sbGw؞?WMJK /:&w1[fbFgdY\oʁ{-OډS!A֯?g9WDC0ׅmujg#S Ag*s<_w:[K_ ǎf4ޤ v}T~צ\ްZe$ɸX(VƤ4oZlO$#>fdnq3"5I(mġFD4 zy}k&l7T}ZKqEYE`(\@/ttL+lK<=KW{wb/[eu.2-Q?ӵDn5R7ew[~:R-O1 |h ʣ+Κ$Z-v.l[?/VQq ]8E~KW6Vm!#檳m> A/K!q6sɢ .m̓&}A{p;1al(Q0c@2&nɄy&)|n2⃹t?C|> E{7ٝSNX/I\I!FLSt3,<fajbύIY&I[8SA:y+綐|ԜvEgUGiwkf}paeI]3=R-h NwH;ʣ(_gxp<\9,cy\H\O'bIx}/Yёl`uM%fT.Dqs^:#47XڀqϤ~:;8pF=z!3 ]>s!/AYa阆Oz{M產=.F6:UWT!}o־9a@VQSae0Θ4?D(,:3EFL9U{L Y3 qX=,"#ADXI_wusIc7tˋeq>/o[M澌MY&,Ui-41$ ;܎Nn,/>a߲ S~==TpySl)s|h[yGu`7|/u ސf'bmH$忊\\c@y$rB*8LDJ|_i[Q*z{$$ln`DXC7%UP"2r|5ͣR¯oԐmzD UUXEX$s,UN+r< 7NzfƓO'f˔{<˔W(lH*rQ}"UVQp>$~e'{9aw "qIsMujIfesE,DNz6j>Ӈ(OHۤesRΫ>osOxr] Ӌ)gc~xl*ѷ1G=uͶo|9σ뫙GD,_ Z=5@X& bed2iVEV5c"=Q/g.?ӵ#k4{TitUȹk\j(}5b^HI? )@N2,-:U ^Tsg :SSs(I*?L>L]qUX#xGpۊ`g|=s=:mM~Db0)NFÑdZDsAnP*LzFnmnK%ED+NH˻'EŸ!e{v endstream endobj 361 0 obj << /Length1 721 /Length2 5243 /Length3 0 /Length 5832 /Filter /FlateDecode >> stream xmrPZ5P*P+ł-RBBHRJqw(NZ] ]9{vs^Da\<ym5^>?3# G!e0Q> Ёx^f neZNPB\ր...R.N\\M:0m X0UA]CMgnP[N0 @,PH(/MN\ @,Qv59: ' #Uv$I pk:?0ACUA\( H|SBZ9{@algB`A;a5h̑/Jh{V;`PM8jKsĽEa wvBQH>y?r@-e9 GZt^;BK]4=wn7<\__d,+ D?r-aH߆o"`n0 )XM|͇BoѢou٧x1 5!wZCTD#~Ej(`8}E.cwVeEo=J; uCt{MA䴝Re|q2m-D?A*MX'VKZfH^,Oce/3SYgٯbYytdWzg}.VbC}DJ/aUֲR+}ծP[yW6JQ G8[am0 ]VoIYk 6}|nz#M H} j]AtLKHd_,~Rɍ?&gf N,1 Gbtwk#kuCWKU*1Ohh.;/v~Fpl`JԤ0 rĀ8;.,W4 \vuŽ8}l0r|5U͗|>yΓ䫗Sj\]W(/hǁ@x* (bA,n ңJcoN:VWRش@$tl=m0e]󌭉Nt) o&ƴ|n!3i4m] |)xZBfF?aov1 PH?/B3<S^56яt.;.zl1 Y?6?NGYB4d&d"kXkH ]SFh6co)糈j&%[SPn2^h9>g&<

=7op܉(ʎT/( Qv l(y .Ewr9_gR.U2.#Ot7)sZC˩/A3S¯PԶL/!ư T/TƐ-r[!+ԇe6>o;VBM)ii]f2t;}"4ږզey)XΒ`l+ɷwNyů\6+7 q 5m}:鍷w\x(g͔u20F+ o} I3(XmDYbD&#CL=61`uN6?NA[mԺإD-W.]%#,n{@vݣfh:ҍI^ŝZ\E.Y;qAzCfDlK*_.T_|'YiW0<cdlTr- ;qP%Ó =dpfeK;J̩<|p7':BjUݶ^/I$G6L֤?XaH?O__rH1*1) Ny~Ў9Gr`nYʨ(~7og/q.0C1wIqW-:|cgdy X`}JE wfp``egtB@Jg'*DCԭTNGni7>y=}0tx3sL|tڝ7#ke0˽` .1`A8hAR$1o'=Z3dT)?0}rUc %sjõ>wV"-8<>jPY,V!}zj.>CbN /\c, I2&iO\-b @U:u+?>8W61YNECHC'VPrȖBgq_$cFeO14Q@TU0}0վO}~/sN5)zJ c-I6cx?ek+\Xy`<Ϥ>'q$Մ͙H֖ܡii(3?tOP!cƮBGUQ~?_DOAfkK+$YW7D6uwNr4qͽD4u2A]ijOvWm#@@{P/^ Ips74`!mdX0lөiqX[9m鋋=jVzC8:e(DO1k|1k sRh<4`4)7LhHdR/wR+uK6 Cc fk4äe֨$)R0arإs{m+A=Qrb{+V?%i5+p}ߟbF(2I /_kL,ڻ^L$L/'G`2&|ln=B=" 2?,M^qS4}߼gW8D Ty>t T{0J(@Sd̒4k}`d-?̉O3XPg{eh/ Sy-ǔT2!@SJ=1 WŬIx.ɾܩ'%77\Ej2i\->] o>haHL586uϋbo>4 SDH>%j-Y |uQ8'-HmwjlJIա\xp{ZDȟֳ:v?ZQś1ZͅWni|Rdj c6uQiy.COUwhan+JnYmPT5$VY.va;CJ~t쩢)Q:{O>XqkIkF6]^8UXy[s6!%l;._.6~^dc뱪Ϫ fF Ӂs1Q>QX03L8 u' 2Ɲ$YbݦZɖfgg v}5G]ߜ+IӼ蔿nm<`~e!i_Z <\m?_-[[\+kě5?:6xtvX0eƅ&eft*G~غd*#R /)xi`7ovmLsä.|ղ)C* endstream endobj 296 0 obj << /Type /ObjStm /N 100 /First 898 /Length 3593 /Filter /FlateDecode >> stream x[[o~ׯ) ; $N|knd{m%W33䮸K$yiQ\p. CA`A2|{& TQG S/$Nfzi0**,( EBi 1F,R@:Jx&GbÄQY : WC >R@'Pǎh%‰^RkGI|v4| vRx8 T3ZɎ`0Ukf Ei, T357@c$s҃3APKxl{\e]$c?t"6qp_,x'c8_H Po|I Sg% zt4#@ A$a ̂Dg31"8X+ŞE:fxv"ڊP؂R0l(|ǓIh^c9@F#@QpEb Ir ;P 58FnBGX MHh1JXC*e(αtٳ?dw[vpZIkq_79R\2W`p  ] ^*.!tو>na0j,mQ)GPόVZf^t- ?}o L)g)0@X<cU~MUW1{ƪCߤwk`/4\t΍8Tg=aZ@kaۣ .TvE{!a>R@ʀӆ.Ş!]<`f}LgX$tЇ1͈i#fԑNo] 1Mv]Ex[p$P٢-õGz;ρSaI2k$r*EƖ2)#紈\CcGdE9Gtx$6Oc47qWYD8hV7v/%od{4H0MHha(Z1!h@Ƕ 0ZYKTQ-i("trݪUV:`w/zK8^hIbgQdj iL3@ mu!0V8f \혦:`BLI{@T/L%n}TEa|fol;f܍8:s]3BO3jrwQ؏my #yb( CAM"8 zcXUɘ8 LgG1e#($49 FDκ ߠIs8Dq9IUy2JX%Q";E9qطx=.w-hnG7ޠ; ؟NXD15Mxx,ˏ'W||§/Q>pSq/v%v*vUva|?/+-!?#@ K@j4 boM}+q aB?,}?PNݸ,;@k Ї_OweOE#Z8f%0x 3 Rzߋ{;DE8Qh =A&`j||w|[)0OYK40O)4 qr:(oU?bTEn5'˿{^~kcXDKb#ԋ뱜Lr@C$nyuR޳2K˂c6 WGS% v%`TE/)렯n("bo61sq9Ybt>#Ĺ[0vjg6h[ѨuJv>Qz F)|ӻק`ٲ,.1C`Z/d]B4.)eӮVkY+p7)&)Kq_Ɣ:aſv `ٖ|;.{UؠLfYlx jo?Lh`n1flU?8{tUǖ}kji`\qǦY%WoѬѮcSNr 0mQ={{||MZ)&EqIfo\ŅKKuuxֲm^3ja5=r_OO,-.- 3we{t|hڰnq|+rz /l-eؖٞrޤ-x/Wk B{B y@ ^oR_l Vy?LzAӻ r J|/j&^L\|@ؖ礋tIKo[}[oK}!^dқwK: 77 llsk[\)asuR[\ԅ1Vj[v=?v/Eصkx;x¨o?OxSA j41u<$v[G#4MXͮ*t]v8YmS,;f &bA} xxsK8}E0eċ#!]H ~k2ӒL3f{;dL LڤrK\e3wVY^*2astm+NMLDCL@JW:U5 ?T֤'iq Rz ٟbaY]me!m5h\~2p|Ec>ݢ!ZUMfȦ_Eeޮ3MWԛ\ŧxO+8|\+T@y[iWis0]^g1skh 9 779vFܬB\qD,Dkp&4 WXUXFXg%k*U^Wyp\.XU!.sU)Zv\хJ׈&"ObA5B/e.@UԨ;gח:' S endstream endobj 390 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.14)/Keywords() /CreationDate (D:20140827165342-04'00') /ModDate (D:20140827165342-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/MacPorts 2013_5) kpathsea version 6.1.1) >> endobj 369 0 obj << /Type /ObjStm /N 22 /First 183 /Length 859 /Filter /FlateDecode >> stream xڕVMo0 W XcDEb=l 8 =dh"uߏd;Iyy"%Y*U+JiciMQ54rX+*h)]9GO 5.CH1]hFKd4T@a1iR+9VZ4q84De@}hT.Vʥɗٵ ߇7U͟" q!uY|u}]%Wvo3MKu’ʇoǸx2om[(h7؜"CQK5Hzդ-C J᥾c#oN3Bp:,o=7 %Pq  Έ=m-F##OImDإJMGmalЍH-ndNS1%HDs?e54ӺpydM2q?{BX88i{Bgb?mgY3np#An`{PlO* R)Pi]aydM낚˶eDdhi!xF!P`]ä.NڑeY3dFǀ+)N2_2yssniUSFQJuy[`H_2uRAX* T@V=HhZdJa |T GxS::Ζ ~JiZrs0ȳo! >mcz#vRj+לY'bFF !?lw\!u_=8#?1L\晸krԨu~oɸBT/v ;ؽKi׬~<7=5˨^4CO endstream endobj 391 0 obj << /Type /XRef /Index [0 392] /Size 392 /W [1 3 1] /Root 389 0 R /Info 390 0 R /ID [<7AD5ABCA30F07ADE4F14BDAFB5EA8988> <7AD5ABCA30F07ADE4F14BDAFB5EA8988>] /Length 989 /Filter /FlateDecode >> stream x%MlTUw̝NC )-RJ,R 6FWWKMX7&nL\49." 6j MhHtF y7Νss=OXNJ8d_JûFe`oKxW*@%NTx/ReAu !xUx:PWlxuxWM 2u-#@o"rh;]@^@vCxx.[{yt- <z`Y}]9Q10̹0Ȋa0NRc<7 &tG|Jkd-; 8e֞f *~e\ (Y^O}-˟PK>QCaP:UsX B ޹q%J+}$"d})M \@CŻܿWq `ɦF nYfA ś6&yrYnPRl7kiTm lsG %#m=W]8@Bn}` !0>Q1֞"/-n; H] a̢֢@P)JNI^bK;ZѸ,"-\ nc  E3,xWS*,_d-@š{jx '3>o7=?$ hbVyA ȚmN^53k ˒` 4h1u5T[NPt/h9A'8d;z^>|SURVuOtoꈥ7U=`_o굸h>_| soOM89a'@sN T6;,`>/+?*awqP.k endstream endobj startxref 446740 %%EOF gWidgets/inst/tests/0000755000176000001440000000000012275245147014207 5ustar ripleyusersgWidgets/inst/tests/ex-glabel.R0000644000176000001440000000036011406427005016157 0ustar ripleyusersw <- gwindow("glabel example", visible=FALSE) widget <- glabel("test label", cont = w) # svalue print(svalue(widget)) # svalue<- svalue(widget) <- "new label" # font font(widget) <- c("weight"="bold", "color"="red") visible(w) <- TRUE gWidgets/inst/tests/README0000644000176000001440000000010111406427005015045 0ustar ripleyusersFiles with .R extenstions are tested within the toolkit packages gWidgets/inst/tests/test-gcombobox.R0000644000176000001440000000177611731163263017273 0ustar ripleyusersif(require(RUnit)) { test.gcombobox <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) items <- letters m <- data.frame(letters[1:4], rep("quit",4), toupper(letters[1:4])) ## basic widget <- gcombobox(items, selected = 1, cont = g) ## svalue checkEquals(svalue(widget), items[1]) checkEquals(svalue(widget, index=TRUE), 1) # index=TRUE ## svalue<- svalue(widget) <- "b" checkEquals(svalue(widget), "b") ## index svalue(widget, index=TRUE) <- 3 checkEquals(svalue(widget), items[3]) ## [ checkEquals(widget[], items) ## [<- widget[] <- m[,1, drop=TRUE] checkEquals(widget[], m[,1,drop=TRUE]) ## data frame widget <- gcombobox(m, cont = g) svalue(widget, index=TRUE) <- 1 checkEquals(svalue(widget, index=TRUE), 1) ## [<- with data frame widget[] <- m[1:2,] svalue(widget, index=TRUE) <- 1 checkEquals(svalue(widget, index=TRUE), 1) } } gWidgets/inst/tests/ex-gtext.R0000644000176000001440000000073411657115526016103 0ustar ripleyusersw <- gwindow("gtext example", visible=FALSE) ## constrouctor -- font.attr sets for buffer widget <- gtext("test text", cont = w, font.attr=list(size=24L, color="blue")) insert(widget, "new text", font.attr=c(family="monospace")) # svalue print(svalue(widget)) # svalue<- svalue(widget) <- "new label" # font<- # sets for buffer if no selection #font(widget) <- list(family="monospace", "weight"="bold", "color"="red", size="xx-large") visible(w) <- TRUE gWidgets/inst/tests/test-gcheckbox.R0000644000176000001440000000057611406427005017242 0ustar ripleyuserstest.gcheckbox <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) text <- "text"; newText <- "newtext" l <- gcheckbox(text, checked=TRUE, cont = g) ## svalue checkEquals(svalue(l), TRUE) ## svalue<- svalue(l) <- FALSE checkEquals(svalue(l), FALSE) ## [ checkEquals(l[], text) ## [<- l[] <- newText checkEquals(l[], newText) } gWidgets/inst/tests/ex-gcheckboxgroup.R0000644000176000001440000000062511406427005017747 0ustar ripleyusersw <- gwindow("test gcheckboxgroup", visible=FALSE) items <- letters[1:4] cbg <- gcheckboxgroup(items, checked= items=="a", cont=w, horizontal=TRUE) ## svalue print(svalue(cbg)) svalue(cbg) <- c(T,F,T,T) print(svalue(cbg)) ## [ print(cbg[]) cbg[] <- letters[12:15] # same length ## handler addHandlerChanged(cbg, handler=function(h,...) { print(svalue(h$obj)) }) visible(w) <- TRUE gWidgets/inst/tests/test-gcalendar.R0000644000176000001440000000061311741715660017226 0ustar ripleyusersrequire(RUnit) test.gcalendar <- function() { w <- gwindow() g <- ggroup(cont = w, horizontal=FALSE) date <- "2009-01-20" ## this fails in rJava -- can't set the initial date ## vanilla cal <- gcalendar(date, cont = g) checkEquals(svalue(cal), date) ## coerce.with cal <- gcalendar(date, coerce.with="as.Date", cont = g) checkEquals(svalue(cal), as.Date(date)) } gWidgets/inst/tests/ex-gslider-gspinbutton.R0000644000176000001440000000101111406427005020726 0ustar ripleyusersw <- gwindow("slider, spinbutton", visible=FALSE) g <- ggroup(cont = w, horiz = FALSE) ## slider sl <- gslider(from=0, to = 100, by =1, value=50, cont = g) ## svalue print(svalue(sl)) ## svalue <- svalue(sl) <- 75 ## handler addHandlerChanged(sl, function(h,...) print(svalue(h$obj))) ## spinbutton sb <- gspinbutton(from=0, to = 100, by =1, value=50, cont = g) ## svalue print(svalue(sb)) ## svalue <- svalue(sb) <- 75 ## handler addHandlerChanged(sb, function(h,...) print(svalue(h$obj))) visible(w) <- TRUE gWidgets/inst/tests/test-gcheckboxgroup.R0000644000176000001440000000146311406427005020313 0ustar ripleyusers## RUnit test ## prefix for function is test. test.gcheckboxgroup <- function() { w <- gwindow() g <- ggroup(cont = w, horizontal = FALSE) items <- letters[1:5] cbg <- gcheckboxgroup(items, checked=c(TRUE,TRUE, FALSE,FALSE,FALSE), cont = g) ## svalue checkEquals(svalue(cbg), items[1:2]) checkEqualsNumeric(svalue(cbg, index=TRUE), 1:2) ## svalue<- ## by logical svalue(cbg) <- c(TRUE,rep(FALSE,4)) checkEquals(svalue(cbg), items[1]) ## by name svalue(cbg) <- items[1:2] checkEquals(svalue(cbg), items[1:2]) ## by index svalue(cbg, index=TRUE) <- 1:3 checkEquals(svalue(cbg), items[1:3]) ## [ checkEquals(cbg[1:2], items[1:2]) checkEquals(cbg[], items[]) ## [<- items <- toupper(items) cbg[] <- items checkEquals(cbg[], items[]) ## clean up dispose(w) } gWidgets/inst/tests/ex-gformlayout.R0000644000176000001440000000665511731162653017324 0ustar ripleyusersw <- gwindow("gformlayout test", visible=FALSE) ## layout a collection of widgets to generate a t.test tTest <- list(type = "ggroup", horizontal = FALSE, children = list( list(type="fieldset", columns = 2, label = "Variable(s)", label.pos = "top", label.font = c(weight="bold"), children = list( list(name = "x", label = "x", type = "gedit", text = ""), list(name = "y", label = "y", type = "gedit", text = "", depends.on = "x", depends.FUN = function(value) nchar(as.character(value)) > 0, depends.signal = "addHandlerBlur" ) ) ), list(type = "fieldset", label = "Hypotheses", columns = 2, children = list( list(name = "mu", type = "gedit", label = "Ho: mu=", text = "0", coerce.with = as.numeric), list(name = "alternative", type="gcombobox", label = "HA: ", items = c("two.sided","less","greater") ) ) ), list(type = "fieldset", label = "two sample test", columns = 2, depends.on = "y", depends.FUN = function(value) nchar(as.character(value)) > 0, depends.signal = "addHandlerBlur", children = list( list(name = "paired", label = "paired samples", type = "gcombobox", items = c(FALSE, TRUE) ), list(name = "var.equal", label = "assume equal var", type = "gcombobox", items = c(FALSE, TRUE) ) ) ), list(type = "fieldset", columns = 1, children = list( list(name = "conf.level", label = "confidence level", type = "gedit", text = "0.95", coerce.with = as.numeric) ) ) ) ) g <- ggroup(horizontal = FALSE, cont = w) fl <- gformlayout(tTest, cont = g, expand=TRUE) bg <- ggroup(cont = g) addSpring(bg) b <- gbutton("run t.test", cont = bg) addHandlerChanged(b, function(h,...) { out <- svalue(fl) out$x <- svalue(out$x) # turn text string into numbers via get() if(out$y == "") { out$y <- out$paired <- NULL } else { out$y <- svalue(out$y) } print(do.call("t.test",out)) }) visible(w) <- TRUE gWidgets/inst/tests/test-gedit.R0000644000176000001440000000045611510500772016375 0ustar ripleyuserstest.gedit <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) text <- "label text"; newText <- "new" l <- gedit(text, cont = g) # svalue checkEquals(svalue(l), text) # svalue<- svalue(l) <- newText checkEquals(svalue(l), newText) # [<- l[] <- state.name } gWidgets/inst/tests/ex-containers.R0000644000176000001440000000166411406427005017106 0ustar ripleyusersw <- gwindow("container", visible = FALSE) size(w) <- c(500,400) pg <- gpanedgroup(cont = w, horizontal=TRUE) ## left part of paned group lg <- ggroup(horizontal = FALSE, cont = pg) # gframe gf <- gframe("frame label", cont = lg, expand=TRUE) gbutton("button", cont = gf) # svalue names(gf)[1] <- "new frame label" ## expand ge <- gexpandgroup("expand group", cont = lg, expand=TRUE) gbutton("button", cont = ge) # visible visible(ge) <- TRUE ## right part of paned group # notebook nb <- gnotebook(cont = pg) gbutton("button", label = "tab label", cont = nb) gbutton("button", label = "tab label", cont = nb) tab <- glayout(label = "tab layout", cont = nb) tab[1,1] <- "label test" tab[2,2] <- gedit("edit widget", cont = tab) tab[3,1:2] <- gedit("expand two", cont = tab) tab[4,1, anchor=c(-1,1)] <- "anchor" # svalue svalue(nb) <- 1 # names<- names(nb)[2] <- "TAB LABEL" size(w) <- c(400,400) svalue(pg) <- 0.5 visible(w) <- TRUE gWidgets/inst/tests/ex-gcheckbox.R0000644000176000001440000000200011406427005016657 0ustar ripleyusersw <- gwindow("checkboxes", visible=FALSE) g <- ggroup(cont = w, horizontal = FALSE) ## checkbox cb <- gcheckbox("label", cont = g) # svalue print(svalue(cb)) # svalue<- svalue(cb) <- FALSE # [ (names) print(cb[]) # [ (names<-) cb[1] <- "new label" # handler addHandlerChanged(cb, function(h,...) print("clicked")) ## radio r <- gradio(letters[1:3], cont = g, horizontal=TRUE) # svalue print(svalue(r)) print(svalue(r, index=TRUE)) #svalue<- svalue(r) <- "b" svalue(r,index = TRUE) <- 3 # [ -- names print(r[]) # [<- r[1] <- "A" r[] <- c("A","B","C") # handler addHandlerChanged(r, handler = function(h,...) print("clicked radio")) ## gcheckboxgroup cbg <- gcheckboxgroup(letters[1:3], cont = g) ## empty? print(svalue(cbg)) ## svalue<- svalue(cbg) <- c(TRUE,TRUE, FALSE) ## svalue print(svalue(cbg)) print(svalue(cbg, index=TRUE)) ## names print(cbg[]) ## [<- cbg[1] <- "A" cbg[] <- c("A","B","C") # handler addHandlerChanged(cbg, handler = function(h,...) print(svalue(h$obj))) visible(w) <- TRUE gWidgets/inst/tests/ex-gedit-gtext.R0000644000176000001440000000115711657107676017204 0ustar ripleyusersw <- gwindow("edit, text", visible=FALSE) g <- ggroup(cont = w, horizontal=FALSE) ## gedit e <- gedit("edit", cont = g) # svalue print(svalue(e)) # svalue<- svalue(e) <- "new text" # handler addHandlerChanged(e, function(h,...) print("changed")) addHandlerKeystroke(e, function(h,...) print(h$key)) ##?? others ## gtext t <- gtext("edit", cont = g) #svalue print(svalue(t)) # svalue<- svalue(t) <- "new text" # insert insert(t, "more new text") # ?\n? insert(t, "even more with font.attr", font.attr = c("color"="red")) # handler addHandlerKeystroke(t, handler=function(h,...) print(h$key)) visible(w) <- TRUE gWidgets/inst/tests/ex-gtable.R0000644000176000001440000000156311657372231016205 0ustar ripleyusers## example to select CRAN mirror m <- getCRANmirrors()[,c(1,4)] setCRAN <- function(URL) { ## see chooseCRANmirror print(URL) repos = getOption("repos") repos["CRAN"] <- gsub("/$", "", URL) options(repos=repos) } w <- gwindow("gtable example",width=400, visible=FALSE) gp <- ggroup(horizontal=FALSE, cont=w) tab <- gtable(m, chosencol = 2, cont=gp, expand=TRUE, handler = function(h,...) setCRAN(svalue(h$obj))) bg <- ggroup(cont=gp) addSpring(bg) gbutton("dismiss", cont=bg, handler = function(h,...) dispose(w)) visible(w) <- TRUE ## test svalue, [] svalue(tab, index=TRUE) <- 2 ## set by index svalue(tab) <- 3 # set by index if 3 is integer svalue(tab) <- m[1,2] # set by values svalue(tab, index=FALSE) <- m[1,2] # explicit set by value tab[] <- head(m) # shrink tab[] <- m # grow gWidgets/inst/tests/test-gimage.R0000644000176000001440000000215411741715664016545 0ustar ripleyusers test.gimage <- function() { require(RUnit) w <- gwindow() g <- ggroup(cont = w, horizontal=FALSE) ## stock icon im <- gimage("help", dirname="stock", cont = g) checkEquals(svalue(im), system.file("images/help.gif",package="gWidgets")) ## svalue<- svalue(im) <- "open" ## size im <- gimage("help", dirname="stock", size="menu", cont = g) im <- gimage("help", dirname="stock", size="small_toolbar", cont = g) im <- gimage("help", dirname="stock", size="large_toolbar", cont = g) im <- gimage("help", dirname="stock", size="button", cont = g) im <- gimage("help", dirname="stock", size="dialog", cont = g) ## filenames im <- gimage("test.png", dirname=".", cont = g) ## svalue<- svalue(im) <- "/Users/verzani/export/Statistics/R/pmg/pmg3/projects/testa.png" } test.icons <- function() { icon <- system.file("images/help.gif",package="gWidgets") ## addStockIcons addStockIcons("testing",icon) im <- gimage("testing", dirname="stock", cont = T) checkEquals(svalue(im), icon) ## getStockIcons lst <- getStockIcons() checkEquals(lst[['testing',exact=TRUE]], icon) } gWidgets/inst/tests/ex-gwindow.R0000644000176000001440000000216611657111071016416 0ustar ripleyusers## Test whether a main window works with ## * menubar ## * toolbar ## * content area ## * statusbar ## toolbar style style="both" f <- function(...) print("hi") a <- gaction(label="action", icon = "quit", handler = f) mbl <- list(File=list( save=gaction("save", icon="save",handler=f), test=a) ) tbl <- list(file=gaction("save",icon="save",handler=f), test = a, stop = gaction("stop", icon="stop",handler=function(...) dispose(w)), quit1 = gaction("quit", icon="quit",handler=f) ) w <- gwindow("test window", visible=FALSE) mb <- gmenu(mbl, cont=w) tb <- gtoolbar(tbl, cont=w, style=style) ## main content txt <- gtext(cont=w) sb <- gstatusbar("status", cont=w) ## test statusbar svalue(sb) <- "This was added to status bar" ## test window svalue(w) <- "title added via svalue" visible(w) <- TRUE ## tests for RUnit test.gwindow <- function() { title <- "test" w <- gwindow(title) checkEquals(svalue(w), title) svalue(w) <- toupper(title) checkEquals(svalue(w), toupper(title)) dispose(w) checkException(svalue(w) <- title) } gWidgets/inst/tests/ex-gcombobox.R0000644000176000001440000000153311406427005016713 0ustar ripleyusersw <- gwindow("combobox example", visible=FALSE) g <- ggroup(cont=w, horizontal = FALSE) m = data.frame(labels = letters[1:3], icons = c("quit","open","file"), tips = paste("the letter", letters[1:3]) ) ## vector argument cb1 = gcombobox(m[,1, drop=TRUE], selected=1, cont =g) # svalue print(svalue(cb1)) print(svalue(cb1, index=TRUE)) #savlue<- svalue(cb1) <- "b" svalue(cb1, index=TRUE) <- 3 # [ print(cb1[]) # [<- cb1[] <- toupper(letters[1:3]) ## handler addHandlerChanged(cb1, handler = function(h,...) print(svalue(h$obj))) ##### Width cb1.5 <- gcombobox(m, width=100, cont = g) ##### editable cb2 <- gcombobox(m[,1,drop=TRUE], editable = TRUE, cont = g) ## svalue<- svalue(cb2) <- "editable" ## svalue print(svalue(cb2)) ## icons? toolkit specific, but should handle this gracefully cb3 <- gcombobox(m, cont = g) visible(w) <- TRUE gWidgets/inst/tests/ex-gdialogs.R0000644000176000001440000000142711406427005016527 0ustar ripleyusersif(interactive()) { w <- gwindow("dialogs example", visible=FALSE) g <- ggroup(cont = w, horizontal = FALSE) ## filebrowse gfilebrowse("select a file", cont = g) ## calendar gcalendar("date", cont = g) ## gfile gbutton("gfile", cont = g, handler = function(...) { out <- gfile() print(out) }) ## gmessage gbutton("gmessage", cont = g, handler = function(h,...) { gmessage("message", title="title", icon = "warning", parent = h$obj) }) ## gconfirm gbutton("gconfirm", cont = g, handler = function(h,...) { out <- gconfirm("confirm", title="title", icon = "warning", parent = h$obj) print(out) }) ## ginput gbutton("ginput", cont = g, handler = function(h,...) { out <- ginput("input", title="title", icon = "warning", parent = h$obj) print(out) }) visible(w) <- TRUE } gWidgets/inst/tests/test-glabel.R0000644000176000001440000000060611406427005016525 0ustar ripleyuserstest.glabel <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) text <- "label text"; newText <- "new" l <- glabel(text, cont = g) # svalue checkEquals(svalue(l), text) # svalue<- svalue(l) <- newText checkEquals(svalue(l), newText) # font<- font(l) <- c("weight"="bold", color="red") # editable l1 <- glabel(text, editable=TRUE, cont = g) } gWidgets/inst/tests/ex-gbutton.R0000644000176000001440000000073411406427005016420 0ustar ripleyusersw <- gwindow("gbutton", visible=FALSE) g <- ggroup(horizontal = FALSE, cont = w) b <- gbutton("button", cont = g) # svalue print(svalue(b)) #svalue<- svalue(b) <- "new button text" ## addHandlerChanged (click) addHandlerChanged(b, function(h,...) print("hi")) # button with icon b1 <- gbutton("quit", cont = g) # action button a <- gaction("action", icon = "quit", handler = function(h,...) print("action")) gbutton(action=a, cont = g) visible(w) <- TRUE gWidgets/inst/tests/test-gradio.R0000644000176000001440000000073411406427005016546 0ustar ripleyuserstest.gradio <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) items <- letters[1:4] l <- gradio(items, selected=1, cont = g) ## svalue checkEquals(svalue(l), items[1]) checkEquals(svalue(l, index=TRUE), 1) ## svalue<- svalue(l) <- "b" checkEquals(svalue(l), "b") svalue(l, index=TRUE) <- 3 checkEquals(svalue(l, index=TRUE), 3) ## [ checkEquals(l[], items) ## [<- l[] <- items[1:4] checkEquals(l[], items[1:4]) } gWidgets/inst/tests/test-gbutton.R0000644000176000001440000000114411510500715016753 0ustar ripleyuserstest.gbutton <- function() { w <- gwindow() g <- ggroup(cont = w, horiz = FALSE) text <- "label text"; newText <- "quit" ## plain vanilla l <- gbutton(text, cont = g) ## svalue checkEquals(svalue(l), text) ## svalue<- svalue(l) <- newText checkEquals(svalue(l), newText) ## font<- font(l) <- c(weight="bold", color="red") # gaction a <- gaction(text, handler = function(h,...) print("hi")) l <- gbutton(action = a, cont =g) checkEquals(svalue(a), text) ## enabled b <- gbutton("asdf", cont=g) enabled(b) <- FALSE checkEquals(enabled(b), FALSE) } gWidgets/inst/images/0000755000176000001440000000000012275245147014312 5ustar ripleyusersgWidgets/inst/images/down.gif0000644000176000001440000000053111406427020015732 0ustar ripleyusersGIF89a"!Created with The GIMP!?,]pH,dH ђTt4)3@#SL q>Px"z3\>""r! rB!m YgHyEA;gWidgets/inst/images/reset.gif0000644000176000001440000000160411406427020016107 0ustar ripleyusersGIF89a?_??___?! ,a 4@*(@B'b(p@r$ȁ q$—"O^P*c @B{ԀG.;*X3*a97a/8HE8bJ_-"P=9h;q9~#4~<2MG;FV/@[(A^2PS>oF(aF;WLFlDE+51&=&232:E5!,Snjrsaswoovwuutuvt _wwqwDwhqWwss__tt4th eXulQ:twugh#hhguc09Lj"!FgFFbB1v;s How;sFFJ@Ab1#myFpc(PiqbȑE 05ƍ$Ij@e"fqIaBE.oҨr'CwX KCrV!Ө`bu9U$PiB.p0n P0"sǎ7SLN@;gWidgets/inst/images/forward.gif0000644000176000001440000000047611406427020016437 0ustar ripleyusersGIF89a!$,[@pH,Hb(,D̦ 5.K: 0 QRlHD@ x  ijXKG! RHA;gWidgets/inst/images/spike.gif0000644000176000001440000000221411406427020016076 0ustar ripleyusersGIF89a              """9!!o,m1)w,'z$'r,4s)8q6.t74s79n# o\Zf{͚W PB aǰvocO_7$&/-BW@r .aɻ@a( ålF%Iڋ8_8I"<xg` Щ9]ɥQc4LL )E1BP##VjD)uII*N @ך'1s&hIq3l1@H:`Ij!9;-lPhD*pIcN7bG> 43>;gWidgets/inst/images/symbol_star.gif0000644000176000001440000000062311406427020017323 0ustar ripleyusersGIF89a$ !,@pBYH# $쌚PQx$IEBh.&B7ϲI$nyr>K@ZtB{$||jZ$ {RZx}$$G${ {|Lqe {]" i~ C$gkB!" L"iZJՁx~Q"x A;gWidgets/inst/images/symbol_rtriangle.gif0000644000176000001440000000062311406427020020341 0ustar ripleyusersGIF89a" !,@#4DB"&jD;Qp^ 4l6"P*D=X2*B#81+%?92,& :3,'!4-&" (#  @ @ @ސ;gWidgets/inst/images/factor.gif0000644000176000001440000000051211406427020016240 0ustar ripleyusersGIF89a5 ,o@P0@qT: @ R!-$`r#_ZI =D( S: DzH z#XQBJWX1XKyMyQ^_XA;gWidgets/inst/images/evaluate.gif0000644000176000001440000000017511406427020016575 0ustar ripleyusersGIF89a9eftʑի!,Bx ;dċ-V!Y[zX9No;VBb= ^3PL$vK1;gWidgets/inst/images/README0000644000176000001440000000033611406427020015157 0ustar ripleyusersIcons for gWidgets. Some were taken from the scigraphica project at sourceforge. Some were manipulated from Dropline Nuovo! http://art.gnome.org/themes/icon/1112. Due to tcltk restrictions, these should be gif files. gWidgets/inst/images/function1.gif0000644000176000001440000000067311406427020016700 0ustar ripleyusersGIF89a2 {{{!, X2Y J&[&)JbXU&TJvJ H&dIYVn)ncm,cJ2+I"BN&N,1$HF`2`*H 2`)2`v2.2(.v/-.\B%0FCI e2*02 22+ (MvN*HQdgN'd|hŀE =,$<1)+@ȉFG ;gWidgets/inst/images/dataframe.gif0000644000176000001440000000116011406427020016706 0ustar ripleyusersGIF89ac """###%%%,Հc Lc/C::=AIA3<(ccC899?GAD H;a]4767AX\``cZ9:@1c^]bbcR`b663L>_c\cǟVc3:;C5c_Q;68^cWc?@@hac@Oa$=-^ f -l@xݧ.)"P@1<1p.,`Cݧ|z$8&˘c;gWidgets/inst/images/symbol_uptriangle.gif0000644000176000001440000000062311406427020020524 0ustar ripleyusersGIF89a$ !,@iHڐ$C$h!Q*iN3$1!V0$BzOp qrx7: CZ$e$ MCC]ET$w$M#z$$C"B#! UMlBB`CC  XD#ch ]jLmcvSFeӓA;gWidgets/inst/images/contour.gif0000644000176000001440000000222611406427020016457 0ustar ripleyusersGIF89ant}zyn>q*~!}7u6~Bz ~'4(,=2$1HIE  $ 1<+%?3*5JB\X % 9/%'("&20?0"9?,*#/+139?180#,%7@@CKIGTS_TG$EAIUO"\%Q;`hpyl+e*ߨ(,+* +>=6 (7/ 49++%-,933$-(>58VCOGHNRZS@KCQ\i:?#%?()5SEHDC#+051)%OE.=5(>BG68#132)-1"%19;=+AI_SkM@JWYAHAK@Udw!,5PE KB ?@E@T&ذ9̈&jU* Zq;~T!$/ 4d  6f܍3V _7Rhf >o߱ w޺wd`*Ayjɢ˗.hЄ%͖.цڲYvE/aa3H:l)+׭Y0#v6h ߼fӤ)c Xtl(F7iڼ{lQ% 7oC (RFбҏEt0!Cڶ&a"? Ub/o `DbJ)'C #0B 30 &@l* 4&@" *@\ 0I"8p;gWidgets/inst/images/arrows.gif0000644000176000001440000000217311406427020016304 0ustar ripleyusersGIF89a      ' * ' >$2O I_\ U YYIO SFY^VQ x l r ~ ysz3*{   & " #"0#/ $!,uW.ъXX` _i̦M+;^ڔSƇK<(0!@=͸,ܨr@aG$%Y/J)efLukOwzHI«ԌVN ޕf犓Dт/us>!_"ZL)**sF+Ca!01UD2AÊ:X3HDIRrv’%ذ ZZ{Ur/3؞2kzq&%~g)wM|h5QsP#>\^BٔHe*Ny4aE +O:6Xc]R˽-J]΃=;A$G!# xFV뺿<} 98@uo_P9Li8D8[ dmv9* `SIENDB`gWidgets/inst/images/3dcontour.gif0000644000176000001440000000213511406427020016705 0ustar ripleyusersGIF89a 5,&,'; IT |di} |!T-b7t0~84Cmj#lM[E6W6\'O&"c utzz?z;C ,(BmFOkoqsM^dhm{}n'+>! %EE,39gIiN[Fepų۠走!,$(CбsM>)ZE B: ޡ("v %dfˋ g!} SgQ.Kd`pA^-rE|J@12F(]TqCdaEB\ ɥcaE`R +6pp6 &@:)XhbRTT47; #' *I0! A6Qd""4)GN{GQ@;gWidgets/inst/images/newplot.gif0000644000176000001440000000240711406427020016457 0ustar ripleyusersGIF89a               !, ) ! 1/"# ,$5=3 < O \ U _KEURVcbj#Y!["Z3Y"e%oDB Kj7 m=u&-x3 q?>z<1z9?u7PqFnLBrDDlIa6&50CTV[SijsL[P^ALDkk`qp!,@AHMP(A,@! P1" a 0(]91WhBEH XP [1B~F[@v䠉 '>??@@AAAABBCCHHGGIIHHIIKKNNMMPPSSQQRRUUUUUUSSTTUUVVWW[[[[[[YYYYZZ[[]]]]bbaa____cc``ddffffeeiiiimmkknnrruuvvxx||}}||||~~΁Նֈ׋яՎϑӑѕҕڔ۔ٕҗ՘ܛܜ٢ؤतڨ۩ߨ۫᭭ᮮ翿!Created with GIMP! ,8+PXU)1SW<YQVROMHEKTIMP%,LA@>FN@JGB?=:DC7;64/9520.3*($ -'"" &"""Ճ#"! `^ F5[pP ;gWidgets/inst/images/cancel.gif0000644000176000001440000000113511406427020016211 0ustar ripleyusersGIF89a\_cfdgOVPWX][_[`glnsmqswz|GQMVNVJTKSOWmumu +)8+6;H8E@MNZU``mV_ir)*++-/@cnv"9ߚ櫵]In^[LG>yya[vrytyuffom킀۶!F,FC0.33./DF/37?22?73/03<659941:30C3A8>E>A3C";==BE=EB=@! E $%# (E#EF"EBB:b*L CA*20h` 2(Ą,!$!4\0! H0 ;gWidgets/inst/images/symbol_dntriangle.gif0000644000176000001440000000062111406427020020477 0ustar ripleyusersGIF89a# !,hfFF4 s)9\D[3x,S3=iF 3QIuGCRL"yCV[PmB#OIW#G yI!#B !F#!G ~mGZE #R~S#RdY~RuHi[" B!R#iOLzA;gWidgets/inst/images/points.gif0000644000176000001440000000222711406427020016303 0ustar ripleyusersGIF89a          %'%#)+).#8 )OG PJ_YU`j gg jpqbqvp ##% 0*!,uJǏϔ`탳(_wV, 8 >X@DTđ.^%.wM\7k ۧv佣T/P4Xc̛h 3cIN,U ZJmAAz0ٹR3"?\!bFV0#PlRLض%DC%C'kmۤMQ+V]@QSd$H7,&d+uKlΒ(q 'jLbcfʔ Jj - \-0H&&jde &pz"4OuqT_Î{mܭ[/0|$"r Ly0R9",k9 !%0@PPA`  VL??O:#=;gWidgets/inst/images/preview.gif0000644000176000001440000000121011406427020016437 0ustar ripleyusersGIF89ajnttiwivjwkxjwkwlxuzziwjxkxnyozr|o{s}vxw|{|~~~zwzww|qstjlnhihijkkmnpii!m,mabkbdclmeM^fmgM==_hmiM77`M* C[?6,,CCF\m\MEE]) EAXmYM@@VMGG@WmUM8.Z(%8TmSM-RMHH:--:HQmQM9&P6dX`Ɠ6LȨI *T8QI%M IÉ 4RѦF;V4!/цD F4 pJh#BDB8!1ǻ8ƙHJSAFHCU/"$! OB!,G.K=emp!CE @@""A0^˴kp)e8u92mԥR"=ጘ Ƴgh}zcA e(F*]: NLkEZ9oBՅ33xU)j[N YၕXg NA" ,wY5&M/,R'TbIC|1t. 8A k@2559sgt@͜*i@h[X $oa1҅J AY`՚Q0MSJD$ x+dC|4 0@$L?]l$x+ӏ/;gWidgets/inst/images/graph.gif0000644000176000001440000000204711406427020016070 0ustar ripleyusersGIF89a                 #! ("#! *- . .1*" +'8'66// 5))7$(75%837?:61B2@HJAD^ F+F&V&M53O>4R5%P84^66ls {f*,y(/t%&.4v79,  8/*:+6@7-)#3;2 1"'&4 . <!5?(=% 0A$ 1P ;gWidgets/inst/images/boxplot.gif0000644000176000001440000000221211406427020016450 0ustar ripleyusersGIF89a          * &5 M OD KOEMWSP W [[^ TVZC"F$D'K&S!U#U%W%R'P#W$W%N&.P%,R'.P).[!0n b`cbfe jk}|a `"k#d d%`(f*i)l*l,p!t!u !t %u &s&{-h$1s 2#%21":6WBWE\B\N`8Y=^Hi!,u@Ղ']U\Ȩ(n,jE+>W0i*"%Tn3dB/mxZ" ')n\J3$e@{A1pjdBF)r<p -xRV֠؄bvye%KR]dtIK⃇M=`hҳ$3+-ZIv(%eA4{S2|S%x3;cN8`@ЁPP@p /p3==<37-8./"1'&$! ;gWidgets/inst/images/file.gif0000644000176000001440000000060211406427020015701 0ustar ripleyusersGIF89a>M9ؓrҬɜhfӕksoqݓݖܶޔޖ޸߸!Created with GIMP! ?,pH, /2y1'JD4Zx6benw!EG%a#gC 7-66. #CKI($4NB2)"02? //&iC,*!+,B   FFA;gWidgets/inst/images/stop.gif0000644000176000001440000000023011406427020015744 0ustar ripleyusersGIF89a«Dzɴʷ̺! ,EpI8[ŻWb$ R⡮qN σB 6 ( P(.?!x X,vfL^D;gWidgets/inst/images/error.gif0000644000176000001440000000113511406427020016115 0ustar ripleyusersGIF89a\_cfdgOVPWX][_[`glnsmqswz|GQMVNVJTKSOWmumu +)8+6;H8E@MNZU``mV_ir)*++-/@cnv"9ߚ櫵]In^[LG>yya[vrytyuffom킀۶!F,FC0.33./DF/37?22?73/03<659941:30C3A8>E>A3C";==BE=EB=@! E $%# (E#EF"EBB:b*L CA*20h` 2(Ą,!$!4\0! H0 ;gWidgets/inst/images/symbol_plus.gif0000644000176000001440000000040611406427020017334 0ustar ripleyusersGIF89a !,'#$jbF^qw\U6!\Bqf;뙐27@< ˯X A9Ӧ;e8 /" :\$Fq$9#I: .=#:I*U"I"U0U7(Q"!;gWidgets/inst/images/history.gif0000644000176000001440000000055411406427020016471 0ustar ripleyusersGIF89aƋ2]LdUlh|2Nn>r~q=}q=~p=z9w9455|70123έ!',P8804.G)O"CQQHZbq($LN  SA6;By&or{BwroB&s B&B odWWWA;gWidgets/inst/images/zoom.gif0000644000176000001440000000163311406427020015753 0ustar ripleyusersGIF89a@ ` @ @@@`@@@@@` `@``````` @` @` @` @`@ @@@`@@@@@ @ @@ @` @ @ @ @ @@@ @@@@@`@@@@@@@@@@`@ `@@`@``@`@`@`@`@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@@ @` @ ` @ @@@`@@@@@` `@``````` @` @`ࠀ @` @` @` @ ` @ @@@`@@@@@` `@``````` @` @` @`𠠤!,x XOz*Ԅ &iJ0ؘРl<@zօ'5ItP$sHX9a..˝ %R=G̢i:؁\zV˲b;gWidgets/inst/images/symbol_cross.gif0000644000176000001440000000062111406427020017501 0ustar ripleyusersGIF89a$ !,@R4"qHi#4*C@Hiy@ eIQ<3tp@Yc8PЀI D$ NO"#C[Jd !OLCEJhTJCJTG$O"b$ T ~hJ ĦLe $_I]Jq]$ $$LT#^A;gWidgets/inst/images/save.gif0000644000176000001440000000204311406427020015721 0ustar ripleyusersGIF89a?@@BD F HILN@PRUTU$M V X""X""Y$$Z&&Z"+T''\((^*3\2;d;DmABsENvKLzKPrLO|PYXZ^^[b[dYfadff]kcjjlirftppitltgztvt{yyr~v}t~z{¦¦§âŪĬ£ƭůȫƨɨɪʲɲʬ˴˴̶ͮİαιϷмжѸ־ֿ!Created with The GIMP! , H@4^8)Ƌ$>Tөԟ PiH .@5ahFF>"S3L*Ԃ@%.%*ԧN2U1@C{ eJ.TH 0 pDvLMZZ`a͏NWbnp݀yyrlhm!F,F (()*,-$.%&' FC//C++4B/#EE"1++8DA/2 77!5A?/03@=/44::6:>;/r1XȰ!CD# ;gWidgets/inst/images/editor.gif0000644000176000001440000000164411406427020016257 0ustar ripleyusersGIF89a??_?_?_??ߟ?ߟ__?߿___!,i` d r!# 0S8p85@r4"+8E ;VkԆN$,f,"Q[v|_l|6vl!;_____?______ߟ__?______߿__?________?________??_???????________?_?_ߟ?_߿?_?_??_???????________?_?_ߟ?_߿?ߟ_ߟߟߟߟߟߟ?_??_???????________?_?_ߟ?_߿?߿_߿߿߿߿߿𠠤, H~$E͞jԶIK $x ډ9# \$J|Xt)`L4"ĉd~@oRgЙDk /!m()B!EHVgXpx*oiu @\;gWidgets/inst/images/refresh.gif0000644000176000001440000000026611406427020016426 0ustar ripleyusersGIF89a??_??ߟ?_?! ,cI7X B 0G@hGr[@$ '%B 4:Iv=32 moI\3C:FDGY;gWidgets/inst/images/1rightarrow.gif0000644000176000001440000000052611406427020017240 0ustar ripleyusersGIF89a<AA@AAABBBCCCFGGHGHHHGHHHIIHIIIIJIMMMNNMNNOOOOPPOPPPTSSUUTUUVUVVVVWWVWZZZ[[[\\\\]\]]]aa`baaabbccbdcdhgghhhhihijijjjnnnooooopppptuuuuuuuvvvv{||||||}}!Created with The GIMP! ?,ZpH,:ѸbKb&{̵2\,-ȃ,SgK% Q QX? ? A;gWidgets/inst/images/alert.gif0000644000176000001440000000050611406427020016074 0ustar ripleyusersGIF89aߘ__aabiڏڑۖܖݚޝ{QUWU[[^dŃ-Dž.ƅ/ɇ0ȇ0ˉ2Ό4ю7ԑ9ה;ה<ڗ>ٖ>ݙ@ܙACޛB΋5Ԑ9!3,cpH,$Xs"V5`0R߃A*xF/ Pēx 'E&1G%%I#$S!"SB A;gWidgets/inst/images/character.gif0000644000176000001440000000104711406427020016722 0ustar ripleyusersGIF89aA;;;<<!4A+(@83-,%7A )2 " .A6  # 9?0%&,1&$,:*%/?;;>;gWidgets/inst/images/help.gif0000644000176000001440000000115211406427020015713 0ustar ripleyusersGIF89am|G[xSfReTfTg]o^ol|j|k|rtstq̴ޝ!O,ǀON   NO+!52$N5*5OF"F FF)1:q$(˖JKǚdJ" ¦/^I3[1hC }đ 7kY҃&5;HUa3dL5X{0yQjɍ<6S K{pЂ |@, A,H"r&r(T%;gWidgets/inst/images/symbol_dot.gif0000644000176000001440000000044511406427020017142 0ustar ripleyusersGIF89a !,y(hyY7XiŎ^= υTF{-^.҈Q`%hQ@4=nlJ[$ v{3Ch+\# Y% C/{"3B,"/#3".R|C#!;gWidgets/inst/images/plot.gif0000644000176000001440000000217111406427020015743 0ustar ripleyusersGIF89a                       ) 0$% = ?_P zut$C/l+|$3 v=)h0/uc=4X;OQ6W`-Nl&H``hg®tpP4ޫsuisQ?8AX\@P@b|ȁcU (ѡ?8Zd(0q"b FPP# 8B'J,>, -ㅇ78PJ_8  BNhhrC!*fLi@FQ0A| ۠\9l-0u);gWidgets/inst/images/logical.gif0000644000176000001440000000047311406427020016402 0ustar ripleyusersGIF89a* ,`@pH,ȤrJ,ʥ:er !^!A P0'|&CosvB FE MrJkL^HiCA;gWidgets/inst/images/symbol_circle.gif0000644000176000001440000000061611406427020017615 0ustar ripleyusersGIF89a% !,,RT0Rƣ,cP!4y&!md xDZy yLLD $ #"%|O\v!_%FxB"\T%o% UL\w rL%a^v%YfF PLBӿnN%\V"T#K$aPgOA;gWidgets/inst/images/density.gif0000644000176000001440000000127011406427020016443 0ustar ripleyusersGIF89a` !,``Z[X_^ %&/4:>!,7 %%9;H<;YH AWBDЖHPhqć60U <:r%H)-! )($0E$.I" %f; x;%'\DD3@$3.* wpiBK];gWidgets/inst/images/arrows1.gif0000644000176000001440000000222211406427020016360 0ustar ripleyusersGIF89a         ' + $?0""$[ _ Q \PW[ i irv y hlovup{#P(/Y    #!,Zv4@a|0B&"D DC@ 'tQS  S[ZF!I! RRA;gWidgets/inst/images/configure.gif0000644000176000001440000000104311406427020016743 0ustar ripleyusersGIF89a-+O:Hg6Fe?Nl(r(q0Cd2De7Ge;KguBx4p4p5q@wX Z=<>BDERNOSĿþĘ![,[HA*,+XO@U/CHM ZE1?O L NZ:Q)>Z K 6V,ZPJZ .+<04I89BQDZ45=R2;7GF3Y T W-S;gWidgets/inst/images/barplot.gif0000644000176000001440000000221611406427020016430 0ustar ripleyusersGIF89a        # !#%&'#()*+-./ $01245789:;<=?'"""ABFJ0478OXDOAENNOVXOWORX[`Wd\f`_eZh^bYaXcZi_adbjnbjkcjeqkrzmuvpxF?A=C=@>BAGDFIKLOONFMPA@BBDCHBIDIHLQSJW[XQ]WS[\[bYa]ac`cqwut}Å!,S: .TْAs.i^[E΀ X0032a ֲV;7pȑHJ]ܴ69+$q9mƼ$ kȱ? ҃ȋ "T 9=a ;uqҚI t6h"JP2I">vS2i#N +e R-^&M,/È Muď=gіH7(Y2@Pyʒ$FlQCđP,\=(3d K'#@D 5 ;0 8\K1Đ H $ !\p QM0,I(2 321Ő;gWidgets/inst/images/subset.gif0000644000176000001440000000203311406427020016267 0ustar ripleyusersGIF89a                "#$! #")#26 #DHZ(1m*k")k50k;1t('{+3x.;x:;{=BwI:_ix֜2$5(4<;!%/<.5&+ 1)=#,)*):2803,84ACFP77GXA4/P==;@@P//AX<)3PE?EB?BEP33:X622PWWP(9X5&''&5X,..%$%,X#(d@"F`B Hp*,  HaX DU0XAr2bN@ HR;gWidgets/inst/images/symbol_ltriangle.gif0000644000176000001440000000062011406427020020330 0ustar ripleyusersGIF89a' !,Rt*N&b!:O#R)Y"sH$$DyH"tf\qx9YtBf'i'' 'IgNSD S'D N''\&'N$`_ P KD\"Mu'' |bW"bzf#GI'&DeE]A;gWidgets/inst/images/1uparrow.gif0000644000176000001440000000052511406427020016546 0ustar ripleyusersGIF89a?BBCCCCCCDDDDHIHIIIIIJJIJJJKJKJKKKNNNOOOOOPPPPQQQUUUVVUVVVVWVWWWWWXWXW[\\\\\\\]\]]]]]]]^^^^bbbbcbcccdcdddchhhiihiiijjjooopooopopppuuuuuvvuuvvvvvw{||||{|||}}}!Created with The GIMP! ?,YpH,Ȥ@X(rI3: C:cPm8@<(P)Ղp:B "&*.269;=C!/379<>OA;gWidgets/inst/images/plot1.gif0000644000176000001440000000174011406427020016025 0ustar ripleyusersGIF89a              $* #2< < =!1# *8.&"&$ 8,GMMZP _KDZ T ]FJCDQXR^ a j qc f eycopp$V"F T(Z"_ C+N%W-V/Y2C* d"e'a(p5r/&]|-s>i/.e=1t,4v:"}75x;6BOHDPHM:@zec)Aj=Db8Pp:QLGA]ER|HFKM~zyX3A:B8H=C)c)p2ppF7@e.-mԴ&)3fP@lA+aK7_ViӆM@;gWidgets/inst/images/symbol_diamond.gif0000644000176000001440000000045011406427020017763 0ustar ripleyusersGIF89a !,y^FV9zYEJdf和'i1RJcUlCRkCWs$*#аHW@x HX⸧lD;4}5%$0zY;=l06vR'@yK$0  $2$guy6:. .:[f:$!;gWidgets/inst/images/up.gif0000644000176000001440000000053111406427020015407 0ustar ripleyusersGIF89a"!Created with The GIMP!?,]pH,*K!`@!Q!L,$`*/+B #N&]<@>|a C!}Qk k#kv?A;gWidgets/inst/images/curve.gif0000644000176000001440000000173711406427020016120 0ustar ripleyusersGIF89a               $,9#") "!&8,$ /EL D KTY S [P _KPYJKG_PX b la epffq~$V T o C.L/K&J%W* d#c"i+f(i z s3b3c'$Y'&rA3i/.e=1i<6u.6:*t80w9Oc)Aj=Db8P{/Vp:Qs"d.h]ER{HDKM464X?D8Y)no??~#,}+-w@C-+$1+22;.?0>7A0@;F9M7H;A0G;HHIH[!,!ȑ !XX!)P`~,j/gΞ;رק% ID,`JU>uM"EԦ2W&a`h;{jg툢'P?KB,k'??Ϟ $̙[aq'& 7eϬ%:)S8b7XOn9yfKi 0_ D!$%sƯ`r:ӥ-\,\;d5&)E MIL=ucpn2ɤ5Ǹ)km 6@&$!$ Í1F {X# 8cMQ;gWidgets/inst/images/symbol_square.gif0000644000176000001440000000043511406427020017653 0ustar ripleyusersGIF89a !,}eI}~qyfm}aF2^SdH"Sj Eq. :Q4M<" xz%q]zq-kX&J&D, ]&qsR[V@RF[|]OH. r&O)S8]!;gWidgets/inst/images/print.gif0000644000176000001440000000056711406427020016130 0ustar ripleyusersGIF89aꡤɽżĵ!?,pH,sȤ9u8{[0s0$-J`OԹ$+-N]9<= &<3  32,,'(!"#""!%% %fI]A;gWidgets/inst/images/quit.gif0000644000176000001440000000023011406427020015741 0ustar ripleyusersGIF89a«Dzɴʷ̺! ,EpI8[ŻWb$ R⡮qN σB 6 ( P(.?!x X,vfL^D;gWidgets/inst/images/open.gif0000644000176000001440000000054611406427020015732 0ustar ripleyusersGIF89a2]0tDvFwFx>>]Ϊ]΄ڄZoXsr6a.R'>5XrI}Qʁn!8,@pH,H%KWXA_‚p<lcIrhV/XX8 znD7 |3C!!!B6 ""#6D4 %$%%%5D* &)D '(' DNHA;gWidgets/inst/images/1downarrow.gif0000644000176000001440000000052411406427020017070 0ustar ripleyusersGIF89a?BBCCCCCCDDDDHIHIIIIIJJIJJJKJKJKKKNNNOOOOOPPPPQQQUUUVVUVVVVWVWWWWWXWXW[\\\\\\\]\]]]]]]]^^^^bbbbcbcccdcdddchhhiihiiijjjooopooopopppuuuuuvvuuvvvvvw{||||{|||}}}!Created with The GIMP! ?,XpH,ȤrrKe u*.g"p5X+Um(`HPOfH̉+'$G# I J LLA;gWidgets/inst/src/0000755000176000001440000000000013650756714013641 5ustar ripleyusersgWidgets/inst/src/ghelp.R0000644000176000001440000005003513650756714015066 0ustar ripleyusers ##' Widget to provide interface to help system setClass("gHelp", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' constructor for help system widget ##' ##' @export ghelp <- function( topic = NULL, package = NULL, container = NULL, ... , toolkit=guiToolkit()){ widget <- .ghelp (toolkit, topic=topic, package=package, container=container ,... ) obj <- new( 'gHelp',widget=widget,toolkit=toolkit) return(obj) } ##' API ##' add, character -- add page character=c(topic), c(topic,package) "package:::topic" ##' add, list -- add page, list(topic, package=NULL) ##' svalue: return list(topic=topic, package=package) ##' length: number of pages ##' dispose: remove current page ##' generic for toolkit dispatch ##' @alias ghelp setGeneric( '.ghelp' , function(toolkit, topic = NULL, package = NULL, container = NULL, ... ) standardGeneric( '.ghelp' )) ################################################## ## ANY imlementation setClass("gHelpANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) setMethod(".ghelp", signature(toolkit="ANY"), function(toolkit, topic=NULL, package=NULL, container = NULL, ...) { # passed to gnotebook force(toolkit) ## check if newversion of R, if so, we con't do a thing but return a label if(!getRversion() >= "2.11.0" && getRversion() < "2.11.0") { gwCat("Needs a new version of R to work.\n") glabel("ghelp", container=container) } nb <- gnotebook(container=container, closebuttons=TRUE, ...) obj <- new("gHelpANY", block=nb, widget=nb, toolkit=toolkit) if(!is.null(topic)) .add(obj, toolkit, value = list(topic=topic, package=package)) invisible(obj) }) ################################################## ## gHelp methods ## workhorse is add -- value is either ## just a topic (not a list), or a list with components topic, package setMethod(".add", signature(toolkit="ANY",obj="gHelpANY", value="character"), function(obj, toolkit, value, ...) { if(length(grep(":",value)) > 0) { # "stats:::t.test" works here tmp = unlist(strsplit(value, ":+")) package = tmp[1] topic = tmp[2] } else { topic = value package = NULL } .add(obj, toolkit, list(topic=topic, package=package)) }) ##' add a page to the help notebook ##' @param obj ghelp object ##' @param toolkit toolkit ##' @param value a list with component topic and value setMethod(".add", signature(toolkit="ANY",obj="gHelpANY", value="list"), function(obj, toolkit, value, ...) { topic <- value$topic package <- value$package nb <- obj@widget ## error check if(!is.character(topic) || length(topic) > 1 || length(topic) == 0) { warning(sprintf("Adding to ghelp needs a valid topic. You tried %s.\n",topic)) return(NULL) } l <- .findHelpPage(topic, package) x <- l$x topic <- l$topic; package <- l$package if(!is.null(x)) { ## are we already present? if(n <- .length(obj, toolkit)) { for(i in 1:n) { l <- list(topic=tag(nb[i],"topic"), package=tag(nb[i],"package")) if(l$topic == topic && ( (is.null(package) | is.null(l$package)) || l$package == package)) { svalue(nb) <- i return(NULL) } } } ## good to go nb <- obj@widget t <- gtext(container=nb, label=topic, expand=TRUE) tag(t, "topic") <- topic tag(t, "pacakge") <- package svalue(nb) <- length(nb) .insertHelpPage(t, x) } return(NULL) }) ##' returns list of topic and package of current page setMethod(".svalue", signature(toolkit="ANY",obj="gHelpANY"), function(obj, toolkit, index=NULL, drop=NULL, ...) { nb <- obj@widget if(n <- length(nb) == 0) return(NULL) if(is.null(index)) index <- svalue(nb) else index <- min(1, max(n, as.integer(index))) page <- nb[index] l <- list(topic=tag(page, "topic"), package=tag(page, "package")) return(l) }) ##' number of pages in notebook setMethod(".length", signature(toolkit="ANY",x="gHelpANY"), function(x, toolkit) { length(x@widget) }) ##' dispose of current page setMethod(".dispose", signature(toolkit="ANY",obj="gHelpANY"), function(obj, toolkit, ...) { dispose(obj@widget) }) ### Helper functions for "add" ##' return help page a set of lines .findHelpPage <- function(topic, package=NULL) { l <- list(topic=topic) if(!is.null(package)) l$package <- package out <- do.call("help", l) if(length(out) == 0) return(NULL) pkgname <- basename(dirname(dirname(out))) ## thanks to Josef L for this help.txt <- "" ## keep R CMD check happy help.con <- textConnection("help.txt", "w", local = TRUE) tools::Rd2txt(utils:::.getHelpFile(out), out=help.con, package=pkgname, width=80L) close(help.con) return(list(x=help.txt,topic=topic, package=pkgname)) } ##' insert help page into text object ##' makes bold if speedy enough .insertHelpPage <- function(obj, x) { isSlow <- obj@toolkit@toolkit == "tcltk" || obj@toolkit@toolkit == "RGtk2" dispose(obj) # clear out <- c() for(i in x) { if(grepl("^_\b",i)) { if(isSlow) out <- c(out, gsub("_\b","",i)) else insert(obj, gsub("_\b","",i), font.attr=c(weight="bold")) } else { if(isSlow) out <- c(out,i) else insert(obj, i,font.attr=c(weight="normal")) } } if(isSlow) svalue(obj) <- out else insert(obj, "", do.newline=FALSE, where="beginning") } ################################################## ## helpers getPossiblePackages = function(topic) { possiblePackages = c() ## find all packages lib.loc <- .libPaths() packages <- .packages(all.available = TRUE, lib.loc = lib.loc) for (lib in lib.loc) { for (pkg in packages) { dir <- system.file(package = pkg, lib.loc = lib) path = utils:::index.search(topic, dir, "AnIndex", "help") if(path != "") possiblePackages = c(possiblePackages, pkg) } } if(length(possiblePackages) == 0) { warning("Adios, can't find a package to match ",topic,"\n") return() } return(possiblePackages) } ################################################## ## This just pops up a window to show the argument from a help page ## Hack to open up help page to the argument showHelpAtArgument = function(argument, topic, package=NULL, width=600, height=250) { if(missing(argument) || missing(topic)) return() if(is.null(package)) { possiblePackages = getPossiblePackages(topic) if(length(possiblePackages) > 0) { package = possiblePackages } else { warning(Paste("Can't find a package containing", topic,"\n")) return() } } ## the widget win=gwindow(Paste("Help on argument: ",topic), visible=FALSE) # set to visible if one is found group = ggroup(horizontal=FALSE, container=win) textwindow = gtext("", container=group, expand=TRUE) size(textwindow) <- c(width,height) for(pkg in package) { ## helpFile = system.file("help",topic,package=pkg) helpFile = help(topic, package=force(pkg), verbose=TRUE)[1] if(helpFile != "") { text = readLines(helpFile) text = sapply(text, function(i) gsub("\\_\\\b","",i)) argPosition = grep(Paste(argument,": "), text) if(length(argPosition) == 0) { next } else { argPosition = argPosition[1] - 1 ##Found one visible(win) <- TRUE # show window } add(textwindow,Paste("From package:",pkg), font.attr=c(weight="bold")) ## add first line (it has a :) add(textwindow,text[argPosition+1],font.attr=c(weight="bold",color="blue")) ## add until a : i = 2; n = length(text) while(length(grep(":",text[argPosition+i])) == 0 && (argPosition + i) <= n ) { add(textwindow,text[argPosition+i],font.attr=c(weight="bold",color="blue")) i = i + 1 } add(textwindow,"\n") } } ## close button buttonGroup = ggroup(container=group) addSpring(buttonGroup) gbutton("cancel", container=buttonGroup, handler = function(h,...) dispose(h$obj)) } ################################################## ## build on ghelp widget to make a browser with search, ## simpler than old pmg.helpBrowser. Break that into components ################################################## ## ghelpbrowser ##' Widget to provide interface to help system setClass("gHelpBrowser", contains="guiComponent", prototype=prototype(new("guiComponent")) ) ##' help browser widget, stand alone window ##' ##' @export ghelpbrowser <- function( title = "Help browser", maxTerms = 100, width = 1000, height = 600 , ..., toolkit=guiToolkit()) { widget <- .ghelpbrowser(toolkit, title=title, maxTerms=maxTerms, width=width ) obj <- new( 'gHelpBrowser',widget=widget,toolkit=toolkit) return(obj) } ##' API: ##' visible<-, logical. Display or hide sidebar ##' size<-, set size of window ##' size, size of window ##' generic for toolkit dispatch ##' @alias ghelpbrowser setGeneric( '.ghelpbrowser' , function(toolkit, title = "Help browser", maxTerms = 100, width = 1000, height = 600 ) standardGeneric( '.ghelpbrowser' )) ## a notebook for holding help pages setClass("gHelpbrowserANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) ################################################## ## build on ghelp widget to make a browser with search, ## simpler than old pmg.helpBrowser. Break that into components ## a notebook for holding help pages setClass("gHelpbrowserANY", contains="gComponentANY", prototype=prototype(new("gComponentANY")) ) setMethod(".ghelpbrowser", signature(toolkit="ANY"), function(toolkit, title = "Help browser", maxTerms=100, width=1000, height=600) { force(toolkit) ## Main widget helpBrowser <- gwindow(gettext("Help browser"), visible=FALSE) ## we need to check what toolkit toolkitType <- helpBrowser@toolkit@toolkit # hackery ##' layout for help search (apropos, pattern) helpSearch <- function(container, ...) { g <- ggroup(horizontal=FALSE, expand=TRUE, container=container, ...) sg <- ggroup(container=g, horizontal=TRUE, fill="x", ...) cb <- gcombobox(c("Apropos", "Pattern"), container=sg) e <- gedit("", container=sg, expand=TRUE, fill="x") sr <- gtable(data.frame("Function"=character(0), Package=character(0), Title=character(0), stringsAsFactors=FALSE), container=g, expand=TRUE, fill="both") addHandlerClicked(sr, handler=function(h,...) { sel <- svalue(h$obj, drop=FALSE) if(!is.null(sel)) { l <- list(topic=sel[[1]], package=sel[[2]]) add(helpWidget, l) } }) searchResultsApropos = function(query) { out = help.search(apropos=query, ignore.case = TRUE) out = out$matches if(nrow(out) > 0) { out = out[1:min(nrow(out),maxTerms),c(1,3,2), drop=FALSE] } else { out = c("no matches","","") } colnames(out) = c("Function","Package","Title") out = as.data.frame(out) for(j in 1:3) out[,j] <- as.character(out[,j]) # avoid factors return(out) } ##' results for help.search searchResultsHelpSearch = function(query) { out = help.search(pattern=query, ignore.case = TRUE) out = out$matches if(nrow(out) > 0) { out = out[1:min(nrow(out),maxTerms),c(1,3,2), drop=FALSE] } else { out = c("no matches","","") } colnames(out) = c("Function","Package","Title") out = as.data.frame(out) for(j in 1:3) out[,j] <- as.character(out[,j]) # avoid factors return(out) } addHandlerChanged(e, handler=function(h,...) { query <- svalue(h$obj) toolkitType <- svalue(cb, index=1) out <- switch(toolkitType, searchResultsApropos(query), searchResultsHelpSearch(query)) sr[] <- out }) } browsePackages <- function(container, ...) { getContentsOfPackage <- function(package) { ## return a data frame with entry keywords description path <- system.file("help", package = package) contents <- readRDS(sub("/help", "/Meta/Rd.rds", path, fixed = TRUE)) return(data.frame(Entry=contents[,'Name'], Keywords=sapply(contents[,"Keywords"], paste, collapse=", "), Description=contents[,'Title'], stringsAsFactors = FALSE)) } emptyDf <- data.frame(Entry=character(0), Keywords=character(0), Description=character(0), stringsAsFactors=FALSE) allPackages <- .packages(all.available=TRUE) curPackage <- NULL g <- ggroup(container=container, horizontal=FALSE, expand=TRUE, ...) g1 <- ggroup(container=g) glabel("Package:", container=g1, anchor=c(1,0)) e <- gedit("", container=g1, anchor=c(-1,0), handler=function(h,...) { val <- svalue(h$obj) if(val %in% allPackages) { curPackage <<- val contents <- getContentsOfPackage(val) fnList[] <- contents } else { curPackage <<- NULL fnList[] <- emptyDf } }) e[] <- allPackages fnList <- gtable(emptyDf, container=g, expand=TRUE) addHandlerClicked(fnList, handler=function(h,...) { topic <- svalue(h$obj) if(nchar(topic)) add(helpWidget, list(topic=topic, package=curPackage)) }) } ##' layout the search pane area layoutSearch <- function(container) { layoutNb <- gnotebook(container=container, expand=TRUE) helpSearch(container=layoutNb, label="Help search") browsePackages(container=layoutNb, label="Browse packages") svalue(layoutNb) <- 1 # first tab } ##' layout the help pane area layoutHelp <- function(container) { tb <- ggroup(container=container, horizontal=TRUE, fill="x") glabel("Help for:", container=tb, anchor=c(1,0)) gedit("", container=tb, anchor=c(-1, 0), handler=function(h,...) { val <- svalue(h$obj) add(helpWidget, val) }) if(toolkitType == "tcltk") { ## dispose if tcltk, otherweise close buttons work gseparator(horizontal=FALSE, container=tb) d <- gbutton("dispose", container=tb, handler=function(h,...) { dispose(helpWidget) }) } if(!toolkitType == "Qt") { ## had errors with running withi handler gbutton("Example", container=tb, handler=function(h,...) { page <- helpWidget[svalue(helpWidget)] do.call("example", list(topic=tag(page, "topic"), package=tag(page, "package"))) }) } addSpring(tb) searchCb <<- gcheckbox("Search box", container=tb, handler=function(h,...) { visible(obj) <- svalue(h$obj) }) helpWidget <<- ghelp(container=container, expand=TRUE, fill="both") } ## widgets pg <- gpanedgroup(container=helpBrowser, horizontal=TRUE) if(toolkitType == "RGtk2") { searchPane <- ggroup(horizontal=FALSE, container=pg) helpPane <- ggroup(horizontal=FALSE, container=pg) } else { helpPane <- ggroup(horizontal=FALSE, container=pg) searchPane <- ggroup(horizontal=FALSE, container=pg) } helpWidget <- NULL # defined in layoutHelp searchCb <- NULL layoutSearch(searchPane) layoutHelp(helpPane) ## show gwindow obj <- new("gHelpbrowserANY", block= helpBrowser, widget=helpBrowser, toolkit=toolkit) tag(obj, "pg") <- pg tag(obj, "searchCb") <- searchCb tag(obj, "toolkitType") <- toolkitType visible(helpBrowser) <- TRUE size(obj) <- c(width, height) visible(obj) <- FALSE # hide sidebar return(obj) }) ##' toggle sidebar setReplaceMethod(".visible", signature(toolkit="ANY",obj="gHelpbrowserANY", value="logical"), function(obj, toolkit, ..., value) { cb <- tag(obj, "searchCb"); svalue(cb) <- value toolkitType <- tag(obj, "toolkitType") pg <- tag(obj, "pg") if(value) { val <- tag(pg, "lastPosition") if(is.null(val) || is.nan(val)) val <- 0.6 val <- max(min(0.75, val), 0.6) if(toolkitType == "RGtk2") val <- 1 - val svalue(pg) <- val } else { tag(pg, "lastPosition") <- svalue(pg) svalue(pg) <- ifelse(toolkitType=="RGtk2",0,1) } obj }) ##' report widget size setMethod(".size", signature(toolkit="ANY",obj="gHelpbrowserANY"), function(obj, toolkit, ...) { w <- obj@widget size(w) }) ##' Set widget size setReplaceMethod(".size", signature(toolkit="ANY",obj="gHelpbrowserANY", value="numeric"), function(obj, toolkit, ..., value) { w <- obj@widget size(w) <- value obj }) gWidgets/inst/install/0000755000176000001440000000000012275245147014513 5ustar ripleyusersgWidgets/inst/install/Installing_gWidgets_toolkits.txt0000644000176000001440000000346311406427020023136 0ustar ripleyusers Installing gWidgets toolkits ----------------------------- The gWidgets package provides a programming interface in R for creating Graphical User Interfaces (GUIs) within R. The gWidgets package interacts with an underlying toolkit package. Currently, RGtk2, tcltk, and rJava have some support. In order to use a GUI toolkit: * the appropriate libraries must be installed * the appropriate R package must be installed * the appropriate gWidgetsXXX package must be installed. The latter two steps are easy, as the packages all reside on CRAN and can be installed through the install.packages command, but successful installation requires prior installation of the proper libraries. The installation of libraries is OS and toolkit specific: RGtk2: RGtk2 requires a version of the GTK+ libraries 2.8.0 or newer. * Linux: Most modern versions of linux ship with a the necessasry GTK libraries. * Mac OS X: The R binary works with a disk image of of the GTK libraries provided by Simon Urbanek. If you install R from source, then the libraries provided by Fink will work. * Windows: Binaries are provided at http://gtk-win.sourceforge.net/ tcltk: gWidgetstcltk uses the newer 8.5 version orhigher of tk. This version introduced theming and many new widgets * Linux: Many versions of Linux come with the 8.4 version. For Ubuntu, the 8.5 versions are available as a pre-built package. * Mac OS X: Mac OS X ships with the 8.4 version of tcl/tk. Upgrading is necessary and can be done through fink if one compiles R from source. * Windows: This version comes bundled into the windows binary rJava: * Linux: A java run time environment must be installed (JRE) * Mac OS X: The java provided with Mac OS X works through the JGR interface to R, but not without this. * Windows: As with linux, a JRE must be installed gWidgets/inst/TODO.txt0000644000176000001440000000503111626245241014344 0ustar ripleyusers* mix C level (like RStudio) and objectSignals to get backend for workspace browser. Polling? * error check input/ouput of main methods * promote do.buttons in gbasidialog to method of .gbasicdialog * Add length.out argument to gslider, gspinbutton * argument to gbutton for icon_only (like compound in tcltk text, icon, both...) * editable<- method (used in gedit), where else? * STARTED. Wish list: roxygen docs on methods; add classes * editable<- method? (Really want for gdf, but could use with gcombobox, glabel, gtext, ... * gaction -- parent argument for key.accelerators. Fix on Control-x, Alt-x, ... use tcltknotation * integrate in column size into gtable size<- (list with columnWidths...) * gcommandline is not very good -- IT IS AWFUL. Do tcltk --- see * size argument in gcombobox as formal argument, we have it as ... now. * methods in docs -- work on API * visible API (not visible<-) with set is wanky, Should deprecate, but need with gbasicdialog * gtable -- help page -- check this DONE * Add multi=FALSE to signature of gfile. DONE * add use.table to gcheckboxgroup DONE * fix ggenericwidget under tcltk -- print twice. gcommandline issue I believe. DONE * fix ghelp to work with windows. DONE * Write API for these guys, even if they aren't implemented DONE * gaction (in gWidgetsWWW) DONE * galert -- like gmessage only appears differently (gWidgetsWWW has implementation) DONE * ghtml widget (for RwxWidgets, gWidgetsWWW) DONE * tooltip (in gWidgetsWWW) NO * gformlayout -- case to be made that depends on should be done in separate pass DONE * add check for toolkit package on startup, if not there pop up GUI based on what exists. DONE * Thomas Petzoldt: doc changes to vignetter: Sweave, others. Search email DONE * tests directory with run tests in each of the toolkits DONE * add addHandlerMouseOver -- for mouseover effects -- different from dropmotion, but similar DONE * gwindow -- place near a parent window, place in some place (setLocatino in rJava), see that TODO DONE * gwindow -- add in menu, toolbar, contentPane, statusbar area. contentPane a "bin"-like container. Done in RGtk2, rJava okay, others need implementing DONE * gframe, gexpandgroup should get a horizontal= argument DONE * FIX FONTS!! weight <-> style DONE getToolkitWidget * export .getWidget, .getBlock, .getParent (Michaels request) DONE * pmg -- close buttons in linux -- read e-mail DONE? * ggroup == on.dragmotion -- not working under windows, linux OK (my guess is that is liew in getWindow()$Raise() DONE ***** gdf -- error with editing see 20 vs 22