hexbin/0000755000175100001440000000000012565120224011544 5ustar hornikusershexbin/TODO0000644000175100001440000000176012371702760012246 0ustar hornikusers-------------- Aug 10, 2014 o get rid of functions in lattice.R, which were copied from lattice -------------- o The new 3D plots -- should rather make the new functions "internal" and choosable with *arguments* from given functions ! o hexbin *class* {as mentioned by man/hexbin.Rd } -- done o find the references (on paper) and read ! --> "References" in ./Biocore-notes ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/eda/bin2d/ ftp://www.galaxy.gmu.edu/pub/faculty/dcarr/software/bin2d.rev/ o example(hmatplot) is still doing many pages instead of one ------------ March 5, 2005 o Implement conversions between different hexagon coordinate systems o Smoothing on a hexagonal basis using tensor products + smoothing histograms + smoothing the intensity of a Poisson process o Family of hex apply functions o Hbin list class and constructors --- o Use standard convertColor() function more and and try to get rid of dependency on 'colorspace' hexbin/inst/0000755000175100001440000000000011551510077012524 5ustar hornikusershexbin/inst/doc/0000755000175100001440000000000012251553257013276 5ustar hornikusershexbin/inst/doc/hexagon_binning.Rnw0000644000175100001440000005204712251553257017133 0ustar hornikusers%% Emacs: use Rnw-mode if available, else noweb %% NOTE -- ONLY EDIT THE .Rnw FILE ! %\VignetteIndexEntry{Hexagon Binning} %\VignetteDepends{hexbin, grid, marray} %\VignetteKeywords{Over plotting, Large data set, Visualization} %\VignettePackage{hexbin} \documentclass[]{article} \usepackage[authoryear,round]{natbib} \usepackage{amsmath} \usepackage{hyperref} \author{Nicholas Lewin-Koh\footnote{with minor assistance by Martin M\"achler}} \begin{document} \title{Hexagon Binning: an Overview} \maketitle{} \section{Overview} Hexagon binning is a form of bivariate histogram useful for visualizing the structure in datasets with large $n$. The underlying concept of hexagon binning is extremely simple; \begin{enumerate} \item the $xy$ plane over the set (range($x$), range($y$)) is tessellated by a regular grid of hexagons. \item the number of points falling in each hexagon are counted and stored in a data structure \item the hexagons with count $ > 0$ are plotted using a color ramp or varying the radius of the hexagon in proportion to the counts. \end{enumerate} The underlying algorithm is extremely fast and effective for displaying the structure of datasets with $n \ge 10^6$. If the size of the grid and the cuts in the color ramp are chosen in a clever fashion than the structure inherent in the data should emerge in the binned plots. The same caveats apply to hexagon binning as apply to histograms and care should be exercised in choosing the binning parameters. The hexbin package is a set of function for creating, manipulating and plotting hexagon bins. The package extends the basic hexagon binning ideas with several functions for doing bivariate smoothing, finding an approximate bivariate median, and looking at the difference between two sets of bins on the same scale. The basic functions can be incorporated into many types of plots. This package is based on the original package for S-PLUS by Dan Carr at George Mason University and is mostly the fruit of his graphical genius and intuition. \section{Theory and Algorithm} Why hexagons? There are many reasons for using hexagons, at least over squares. Hexagons have symmetry of nearest neighbors which is lacking in square bins. Hexagons are the maximum number of sides a polygon can have for a regular tesselation of the plane, so in terms of packing a hexagon is 13\% more efficient for covering the plane than squares. This property translates into better sampling efficiency at least for elliptical shapes. Lastly hexagons are visually less biased for displaying densities than other regular tesselations. For instance with squares our eyes are drawn to the horizontal and vertical lines of the grid. The following figure adapted from \cite[]{carretal}shows this effectively. \begin{figure}[H] \centering <>= library("hexbin")#,lib.loc="/home/nikko/R-devel/hex.devel/tst") x <- rnorm(1000) y <- rnorm(1000) ##-- Hexagon Bins: -- hbin <- hexbin(x,y, xbins = 25) grid.newpage() pushViewport(viewport(layout=grid.layout(1, 2))) pushViewport(viewport(layout.pos.col=1,layout.pos.row=1)) plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE) popViewport() ##-- Manual "square" binning: -- ## grid rx <- range(x); bx <- seq(rx[1],rx[2], length=29) ry <- range(y); by <- seq(ry[1],ry[2], length=29) ## midpoints mx <- (bx[-1]+bx[-29])/2 my <- (by[-1]+by[-29])/2 gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2) zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28 ind <- zz > 0 if(FALSE) ## ASCII image: symnum(unname(ind)) sq.size <- zz[ind]^(1/3) / max(zz) ## if we used base graphics: ## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2) pushViewport(viewport(layout.pos.col=2, layout.pos.row=1)) vp <- plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE, type="n") pushHexport(vp$plot, clip="on") grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size, default.units = "native", gp = gpar(col="black",fill="black")) popViewport() @ \caption[bivariate: squares and hexagons]{A bivariate point set binned into squares and hexagons. Bins are scaled approximately equal, and the size of the glyph is proportional to the count in that bin.} \label{fig:compHexSq} \end{figure} We can see in Figure~\ref{fig:compHexSq} that when the data are plotted as squares centered on a regular lattice our eye is drawn to the regular lines which are parallel to the underlying grid. Hexagons tend to break up the lines. How does does the hexagon binning algorithm work? \begin{enumerate} \item Squash $Y$ by $\sqrt{3}$ \item Create a dual lattice \item Bin each point into pair of near neighbor rectangles \item Pick closest of the rectangle centers (adjusting for $\sqrt{3}$) \end{enumerate} << nearNeighbor, echo = false, results = hide >>= x <- -2:2 sq <- expand.grid(list(x = x, y = c(-1,0,1))) fc.sq <- rbind(sq,sq+.5) # face centered squares fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3) nr <- length(fc.sq$x)/2 @ \begin{figure}[H] \centering << fig = TRUE,width = 4,height = 8,echo = FALSE >>= par(mfrow = c(3,1)) par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) points(-.25,.15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1)+1 py <- sqrt(3)*(c(0,0,-1,-1)+1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) points(-.25, .15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1) + 1 py <- sqrt(3)*(c(0,0,-1,-1) + 1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) px <- c(-.5,-.5,0,.5, .5, 0) py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3) polygon(px, py, col = gray(.5), density = 0) polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4) points(-.25, .15, col = 2, pch = 16, cex = .5) plot.new() arrows(-.25, .15, 0, 0, angle = 10, length = .05) @ \caption[Near Neighbor Rectangles]{} \label{fig:binalg} \end{figure} Figure~\ref{fig:binalg} shows graphically how the algorithm works. In the first panel we see the the dual lattice laid out in black and blue points. The red point is an arbitrary point to be binned. The second panel shows the near neigbor rectangles for each lattice around the point to be binned, the intersection of the rectangles contains the point. The last panel shows the simple test for locating the point in the hexagon, the closest of the two corners which are not intersections is the center of the hexagon to which the point should be allocated. The binning can be calculated in one pass through the data, and is clearly $O(n)$ with a small constant. Storage is vastly reduced compared to the original data. \section{Basic Hexagon Binning Functions} Using the basic hexagon binning functions are not much more involved than using the basic plotting functions. The following little example shows the basic features of the basic plot and binning functions. We start by loading the package and generating a toy example data set. << basic, fig = TRUE, results = hide >>= x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40) plot(hbin) @ There are two things to note here. The first is that the function \texttt{gplot.hexbin} is defined as a \texttt{plot} method for the S4 class \texttt{hexbin}. The second is that the default color scheme for the hexplot is a gray scale. However, there is an argument to plot, \texttt{colramp}, that allows the use of any function that excepts an argument \texttt{n} and returns $n$ colors. Several functions are supplied that provide alternative color-ramps to R's built in color ramp functions, see \texttt{help(ColorRamps)}. << showcol, fig = TRUE, width = 7, height = 4, echo = FALSE >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40, shape = shape) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = terrain.colors) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = BTY) popViewport() @ The figure shows three examples of using hexagons in a plot for large $n$ with different color schemes. Upper left: the default gray scale, upper right: the R base \texttt{terrain.colors()}, and lower middle: \texttt{BTY()}, a blue to yellow color ramp supplied with hexbin on a perceptually linear scale. The hexbin package supplies a plotting method for the hexbin data structure. The plotting method \texttt{gplot.hexbin} accepts all the parameters for the hexagon function and supplies a legend as well, for easy interpretation of the plot. Figure~2 shows a hex binned plot with a legend. A function \texttt{grid.hexlegend} is supplied for creating user specified hexagon legends. \section{Extended Hexagon Functions} So far we have looked at the basic hexagon plot. The hexbin package supplies several extensions to the basic hexbin, and the associated hexplot. The extensions discussed in this section will be smoothing hexbin objects using the hsmooth function, approximating a bivariate median with hexagons and a version of a bivariate boxplot, and using eroded hexbin objects to look at the overlap of two bivariate populations. \subsection{Smoothing with \texttt{hsmooth}} At this point the hexbin package only provides a single option for smoothing using a discrete kernel. Several improvements are in development including an apply function over neighborhoods and spline functions using a hexagonal basis or tensor products. The apply function should facilitate constructing more sophisticated kernel smoothers. The hexagon splines will provide an alternative to smoothing on a square grid and allow interpolation of hexagons to finer grids. The current implementation uses the center cell, immediate neighbors and second neighbors to smooth the counts. The counts for each resulting cell is a linear combination of the counts in the defined neighborhood, including the center cell and weights. The counts are blurred over the the domain, and the domain increases because of shifting. Generally the dimension of the occupied cells of the lattice increases by one, sometimes two. Some examples of using the hsmooth function are given below. Notice in the plots that the first plot is with no smoothing, weights are \texttt{c(1,0,0)} meaning that only the center cell is used with identity weights. The second plot shows a first order kernel using weights \texttt{c(24,12,0)}, while the third plot uses weights for first and second order neighbors specified as \texttt{c(48,24,12)}. The code segment generating these plots rescales the smoothed counts so that they are on the original scale. << showsmth, fig = TRUE, width = 8, height = 4, echo = FALSE >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) x <- rnorm(10000) y <- rnorm(10000) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"), "inches"), convertHeight(unit(1,"npc"), "inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) hbin <- hexbin(x,y, xbins = 30,shape = shape) hsmbin1 <- hsmooth(hbin, c( 1, 0,0)) hsmbin2 <- hsmooth(hbin, c(24,12,0)) hsmbin2@count <- as.integer(ceiling(hsmbin2@count/sum(hsmbin2@wts))) hsmbin3 <- hsmooth(hbin,c(48,24,12)) hsmbin3@count <- as.integer(ceiling(hsmbin3@count/sum(hsmbin3@wts))) pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1)) plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() @ \subsection{Bin Erosion and the \texttt{hboxplot}} The next tool to introduce, gray level erosion, extends the idea of the boxplot. The idea is to extract cells in a way that the most exposed cells are removed first, ie cells with fewer neighbors, but cells with lower counts are removed preferentially to cells with higher counts. The algorithm works as follows: Mark the high count cells containing a given fraction, cdfcut, of the total counts. Mark all the cells if cdfcut is zero. The algorithm then performs gray-level erosion on the marked cells. Each erosion cycle removes counts from cells. The counts removed from each cell are a multiple of the cell's exposed-face count. The algorithm chooses the multiple so at least one cell will be empty or have a count deficit on each erosion cycle. The erode vector contains an erosion number for each cell. The value of erode is \begin{center} $6\times$(The erosion cycle at cell removal) $ - $ (The cell deficit at removal) \end{center} The cell with the highest erosion number is a candidate bivariate median. A few ties in the erosion order are common. The notion of an ordering to the median is nice because it allows us to create a version of a bivariate box plot built on hexagons. The following example comes from a portion of the ''National Health and Nutrition Examination Survey'' included in \texttt{hexbin} as the sample data set NHANES. The data consist of 9575 persons and mesures various clinical factors. Here in Figure~\ref{hbox} we show the levels of transferin, a measure of iron binding against hemoglobin for all \begin{figure}[H] \centering << hbox, fig = TRUE, width = 6, height = 4, echo = FALSE >>= data(NHANES) #grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) #vpin <- c(convertWidth (unit(1,"npc"), "inches"), # convertHeight(unit(1,"npc"), "inches")) vpin <- c(unit(6,"inches"),unit(4, "inches")) shape <- optShape(height = vpin[2], width = vpin[1], mar = mai) hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape) hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3) pushHexport(hbhp,clip = 'on') hexGraphPaper(hb,fill.edges = 3) popViewport() @ \caption{Hexagon "boxplots" showing the top 95 percent of the data for males and females. The red hexagons are an estimate of the bivariate median.} \label{hbox} \end{figure} Note that we have added ``hexagon graph paper'' to the plot. This can be done for any hexbin plot, using the command \texttt{hexGraphPaper()} where the main argument is the hexbin object. \subsection{Comparing Distributions and the \texttt{hdiffplot}} With univariate data, if there are multiple groups, one often uses a density estimate to overlay densities, and compare two or more distributions. The hdiffplot is the bivariate analog. The idea behind the hdiff plot is to plot one or more bin objects representing multiple groups to compare the distributions. The following example uses the National Health data supplied in the hexbin package, (\texttt{NHANES}). Below we show a comparison of males and females, the bivariate relationship is transferin, which is a derived measure of the ability of blood to bind oxygen, vs the level of hemoglobin. Note that in the call to \texttt{hdiffplot} we erode the bins to calculate the bivariate medians, and only display the upper 75\% of the data. \begin{figure}[H] \centering << hdiff, fig = TRUE, width = 6, height = 4, echo = TRUE >>= #grid.newpage() shape <- optShape(height = vpin[2],width = vpin[1],mar = mai) xbnds <- range(NHANES$Transferin,na.rm = TRUE) ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE) hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"], NHANES$Hemoglobin[NHANES$Sex == "F"], xbnds = xbnds, ybnds = ybnds, shape = shape) hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"], NHANES$Hemoglobin[NHANES$Sex == "M"], xbnds = xbnds, ybnds = ybnds, shape = shape) plot.new() hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3) @ \caption{A difference plot of transferin vs hemoglobin for males and females.} \label{hdiffplot} \end{figure} \subsection{Plotting a Third Concomitant Variable} In many cases, such as with spatial data, one may want to plot the levels of a third variable in each hexagon. The grid.hexagons function has a pair of arguments, \texttt{use.count} and \texttt{cell.at}. If \texttt{use.count = FALSE} and \texttt{cell.at} is a numeric vector of the same length as \texttt{hexbin@count} then the attribute vector will be used instead of the counts. \texttt{hexTapply} will summarize values for each hexagon according to the supplied function and return the table in the right order to use as an attribute vector. Another alternative is to set the \texttt{cAtt} slot of the hexbin object and grid.hexagons will automatically plot the attribute if \texttt{use.count = FALSE} and \texttt{cell.at = NULL}. Here is an example using spatial data. Often cartographers use graduated symbols to display varying numerical quantities across a region. \section{Example: cDNA Chip Normalization} This example is taken from the marray package, which supplies methods and classes for the normalization and diagnostic plots of cDNA microarrays. In this example the goal is not to make any comments about the normalization methodology, but rather to show how the diagnostic plots can be enhanced using hexagon binning due to the large number of points ($n = 8,448$ cDNA probes per chip). We look at the diagnostic plot $M$ vs $A$, where $M$ is the log--ratio, $M = \log <- 2 \frac{R}{G}$ and $A$ is the overall intensity, $A = \log <- 2\sqrt{RG}$. Figure~3 shows the plot using points and on the right hexagons. The hexagon binned plot shows that most of the pairs are well below zero, and that the overall shape is more like a comet with most of the mass at the bottom of the curve, rather than a thick bar of points curving below the line. << marray1, fig = TRUE, results = hide >>= ### Need to redo this part. library("marray") data(swirl, package = "marray") ## use swirl dataset hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 2))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M', main = "M vs A plot with points", legend = 0, newpage = FALSE) pushHexport(nb$plot.vp) grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4)) popViewport() nb$hbin <- hb1 hexVP.abline(nb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(nb) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) hb <- plotMAhex(swirl[,1], newpage = FALSE, main = "M vs A plot with hexagons", legend = 0) hexVP.abline(hb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(hb) popViewport() @ \section{Manipulating Hexbins} The underlying functions for hexbin have been rewritten and now depend on the grid graphics system. The support unit for all hexagon plots is the hexViewport. The function \texttt{hexViewport()} takes a hexbin object as input and creates a viewport scaled to the current device or viewport so that the aspect ratio is scaled appropriately for the hexagons. Unlike in the base graphic functions where the aspect ratio is maintained by shifting the range of the axes, here the extra space is shifted into the margins. Currently hexViewport returns a hexViewport object that has information on the margins and its own pushViewport method. In the next example we will 1st show how to manipulate an existing plot using grid commands and second show how to create a custom plotting function using \texttt{hexViewport} and grid. \subsection{Adding to an existing plot} Adding to an existing plot requires the use of grid functions. For instance, in the following code, << addto,fig = TRUE,echo = TRUE >>= hplt <- plot(hb1,style = 'centroid',border = gray(.65)) pushHexport(hplt$plot.vp) ll.fit <- loess(hb1@ycm ~ hb1@xcm, weights = hb1@count, span = .4) pseq <- seq(hb1@xbnds[1]+1, hb1@xbnds[2]-1, length = 100) grid.lines(pseq, predict(ll.fit,pseq), gp = gpar(col = 2), default.units = "native") @ we have to use \texttt{grid.lines()}, as opposed to \texttt{lines()}. \end{document} hexbin/inst/doc/hexagon_binning.R0000644000175100001440000002107012251553257016556 0ustar hornikusers### R code from vignette source 'hexagon_binning.Rnw' ################################################### ### code chunk number 1: comphexsq ################################################### library("hexbin")#,lib.loc="/home/nikko/R-devel/hex.devel/tst") x <- rnorm(1000) y <- rnorm(1000) ##-- Hexagon Bins: -- hbin <- hexbin(x,y, xbins = 25) grid.newpage() pushViewport(viewport(layout=grid.layout(1, 2))) pushViewport(viewport(layout.pos.col=1,layout.pos.row=1)) plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE) popViewport() ##-- Manual "square" binning: -- ## grid rx <- range(x); bx <- seq(rx[1],rx[2], length=29) ry <- range(y); by <- seq(ry[1],ry[2], length=29) ## midpoints mx <- (bx[-1]+bx[-29])/2 my <- (by[-1]+by[-29])/2 gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2) zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28 ind <- zz > 0 if(FALSE) ## ASCII image: symnum(unname(ind)) sq.size <- zz[ind]^(1/3) / max(zz) ## if we used base graphics: ## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2) pushViewport(viewport(layout.pos.col=2, layout.pos.row=1)) vp <- plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE, type="n") pushHexport(vp$plot, clip="on") grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size, default.units = "native", gp = gpar(col="black",fill="black")) popViewport() ################################################### ### code chunk number 2: nearNeighbor ################################################### x <- -2:2 sq <- expand.grid(list(x = x, y = c(-1,0,1))) fc.sq <- rbind(sq,sq+.5) # face centered squares fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3) nr <- length(fc.sq$x)/2 ################################################### ### code chunk number 3: hexagon_binning.Rnw:138-170 ################################################### par(mfrow = c(3,1)) par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) points(-.25,.15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1)+1 py <- sqrt(3)*(c(0,0,-1,-1)+1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) points(-.25, .15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1) + 1 py <- sqrt(3)*(c(0,0,-1,-1) + 1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) px <- c(-.5,-.5,0,.5, .5, 0) py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3) polygon(px, py, col = gray(.5), density = 0) polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4) points(-.25, .15, col = 2, pch = 16, cex = .5) plot.new() arrows(-.25, .15, 0, 0, angle = 10, length = .05) ################################################### ### code chunk number 4: basic ################################################### x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40) plot(hbin) ################################################### ### code chunk number 5: showcol ################################################### #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40, shape = shape) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = terrain.colors) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = BTY) popViewport() ################################################### ### code chunk number 6: showsmth ################################################### #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) x <- rnorm(10000) y <- rnorm(10000) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"), "inches"), convertHeight(unit(1,"npc"), "inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) hbin <- hexbin(x,y, xbins = 30,shape = shape) hsmbin1 <- hsmooth(hbin, c( 1, 0,0)) hsmbin2 <- hsmooth(hbin, c(24,12,0)) hsmbin2@count <- as.integer(ceiling(hsmbin2@count/sum(hsmbin2@wts))) hsmbin3 <- hsmooth(hbin,c(48,24,12)) hsmbin3@count <- as.integer(ceiling(hsmbin3@count/sum(hsmbin3@wts))) pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1)) plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() ################################################### ### code chunk number 7: hbox ################################################### data(NHANES) #grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) #vpin <- c(convertWidth (unit(1,"npc"), "inches"), # convertHeight(unit(1,"npc"), "inches")) vpin <- c(unit(6,"inches"),unit(4, "inches")) shape <- optShape(height = vpin[2], width = vpin[1], mar = mai) hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape) hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3) pushHexport(hbhp,clip = 'on') hexGraphPaper(hb,fill.edges = 3) popViewport() ################################################### ### code chunk number 8: hdiff ################################################### #grid.newpage() shape <- optShape(height = vpin[2],width = vpin[1],mar = mai) xbnds <- range(NHANES$Transferin,na.rm = TRUE) ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE) hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"], NHANES$Hemoglobin[NHANES$Sex == "F"], xbnds = xbnds, ybnds = ybnds, shape = shape) hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"], NHANES$Hemoglobin[NHANES$Sex == "M"], xbnds = xbnds, ybnds = ybnds, shape = shape) plot.new() hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3) ################################################### ### code chunk number 9: marray1 ################################################### ### Need to redo this part. library("marray") data(swirl, package = "marray") ## use swirl dataset hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 2))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M', main = "M vs A plot with points", legend = 0, newpage = FALSE) pushHexport(nb$plot.vp) grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4)) popViewport() nb$hbin <- hb1 hexVP.abline(nb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(nb) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) hb <- plotMAhex(swirl[,1], newpage = FALSE, main = "M vs A plot with hexagons", legend = 0) hexVP.abline(hb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(hb) popViewport() ################################################### ### code chunk number 10: addto ################################################### hplt <- plot(hb1,style = 'centroid',border = gray(.65)) pushHexport(hplt$plot.vp) ll.fit <- loess(hb1@ycm ~ hb1@xcm, weights = hb1@count, span = .4) pseq <- seq(hb1@xbnds[1]+1, hb1@xbnds[2]-1, length = 100) grid.lines(pseq, predict(ll.fit,pseq), gp = gpar(col = 2), default.units = "native") hexbin/inst/doc/hexagon_binning.pdf0000644000175100001440000136321511704527653017144 0ustar hornikusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 3564 /Filter /FlateDecode /N 97 /First 773 >> stream x[[s8~_kq*v=y%,)*̯DNf{kSe xpp.9HH)4L V3˔1#*sJ03 T9UU  t$^`% kͤZ&ѤLjxdR hwLzGs`*H-$U:0=S6aa.1;0L ?5KmrKmŴàIΆi$P$FBO *Ɯ 2c zzȌPF3`/ceV@(tƂVBp͙5W u7Hl5Z$ĸ'" r\YAy0I\pN3k"f^21T~`W#y@#)&wp+B@4OR6VB  fa%*y*0:b6"x11 p,TA@UѰ)̈́9;gWG+ai2:guQhZ ti\m\dzx2G.c8 %~ZLc˧O+ Ϗz5AQ9ոdhiB_L( $f%o~s7!oPǵ^kcncc?y/dypzmp6mpy./^bw˃kc|ul؇)?U*$袒*-*&3OXMu;LCDƟ.G 棺_-<čy אdZer3Jh4|i5m&ϓplG>BBf(q+!1،rw`E1f3V)UbZY;tP.J>:ƈfqdrr3"9rDpNAb[Zy6bK.lë/O(N//G6zXl;FBvwvO9GV43}:Si˧`Us J<0Q:hhJwW9=טva%x{9i$J&3U3(y]ބ6irl^aoԯJ,IgcpOgJǙ)OjpTܔpyWZj8:>5堼i *M&u)L{Uݛ ʏ7ՠW_%g:xhjx/o =k0(:wmQOGa+"ɸdB;xW;z7~xW"vn*9Cܺx^@wW')-ײ\vnvbE=bBE vf4eಀU4.ՎlqoLr+|"ںEW6zT>?9i_ZwW_[X^l2֛/Fu۰v+ ﶕt6gk%'x̯䄎-w}wŚ1 9)W$IzhfN;lQ& /q]NIjZAIj?WHabkH/R=hRջb^IU_F,ꚯ]x`4k+ǀQ‚n;}Z lYDGq[={u@ۭ[Nbש^|VxW~Z5v`?#0eއLc[h2Ln3Ŭ,y"5@:]߃ (4?[/]LĚs.L2Mv)Erm:o!^[!o*7J:u)EIRIؘb(RfrVvL3CȲxV uRxbOM,mC (#*Jn-;&73hT9tTK^3tuˑ i= F$=l#|Y+R]C:rP\K֠5.3g"" %}' I5$0=Kr%aЇ2*r~Ӗ=I%ɬaD, ?̉j*z’v3e$.  `fdkULP Adz;>C.ca),YԺT]cNHg6 _IjGVZ"Z"R%5vGO Oj}[5o9E.ÛY,]uL;ދK> +2uPA@"Ӥ@r ֋-eӖNEEO%SS6 Sbp#:ƘxdNr&.m (ï$s2Ҋ>v~Ց9USiKMt Cd3$]cnVVʼnZg@ej ʵ \CsKϒR-7ISـa1~QVwغw2aWNh;?}Sz k=Mcف$ #ߧ6 RH%LW̝4Š=ނ4ॻΗ=~ |GI>㲮F}^ TyÛ,yLjO?h-__7\>!6rg>~^Zy#HYl>ARz{nRx1*I>)?@'WYvg7EhXuQj to;Mi-9҂^UŗlhV6ўm=ٰ7x459~뎇g49&4`:NNR.]s.IRwKeo͎F-vz)"c!YW'UgˆNiPw 5l*z_'fE{XJM{3%7k4^OM%úsjI%5.ObW&t~5m0mB ˛I9{aWIL; wt??j&6QASQ ;}+EgWt0.CfqyWMg:;z<e_粞aT&4\(tأ^&`ɋ7~ݤ,؇l$ltp?~~PVqGI?endstream endobj 99 0 obj << /Filter /FlateDecode /Length 2269 >> stream xڍX˲߯h A2Jʓy9NRs]Y^]DYfFݧAx!ot7޽|kSe֔ENLSe7%_ɷ_V3~joC8&kgu^%s[gucޯq~{=m+>+1;rI5Unfus]g4*$"2NqsϠ竍gҶ 9 /GWfɼ3ln 8Kҩ&k<1BD!A a:}S=MȺEthY6^o%[>nX#S{ӆzB9E33g!NDH޶_A̰qEYM$bcm4]PfMټ2>}Up)Jt j: x&h_wT BDsCTTR|EmvuSCJc&!僌 y4x,&Qb.Ϭ7A"n#7 R= ]Eñ jGDUU'\yjLEy@3EtQ_ݯ8J}{v-a6#+X>ߏ^;%oWY8 QYC31Mpf`[Fs56k*b V ?;+,$0B佑 { 8Vi'@/ Na:3v[ZU.XrXu]m)Tm ߑFL 5r\;vhxSJ>23YEQ]rh{V"NB*}YyȐzezn*'A6JȪzNo˯!7M8ݩ񝕿]Y8]76# B') U7E X7]pD*u$Mrq.0,mHU&Uu#0ipUHݍ(K % \3Dh)%MVRcR[>5u k"vx։(b?RdoyxWe2NR[pw)-c>CRX!Ki3RFoCR2Z(C*h笆glDRi6؇&—2tRؿ|ю,AYHjP@a5:yƤ=#w,#D;,mkOUozyaJFx+ 0=17 cn28?e&&X]H"2\:!E`.v!Kѥ!vAw@"_%Рx<(Ǧ0D2xPb$~hOԚBW%s1 #a"X{{CʱӐ]\D *@l V#qr"b^ ^$ƹu:OdI$5uhi5XUVd25ѳ7{zVl xZ) ^e 'G}Q0IZp#> stream xZnH}߯-Š\:޾.J,myd9*ٖd9qf؇XEK O8KOtj\nAka/w|5-Ԟ؁BIH o|ZbyQ-kwN=Gnu~8oP?2`޻:P+c#.vQ6!p֙m\ʲP*~d{߳~֡(%(:yv&[Ŝ%klrS>,ec!HO#r!:{A=ᴜ-V,몸Y:?.nog# unJMfjRTcvZG嬨3L$4o pD+a!#6 aD}/oQ E ߓ>~zo~baӗW_?S?wntaƭ맞qQ9eqO$E_ ִau-Fz?BoTm%t۵J"Qx2<'{_zߵi;@( (20&t]endstream endobj 197 0 obj << /Filter /FlateDecode /Length 2437 >> stream xڵێJ}"/HݾJ1: $@;yplO։gdgndz q_^5>>*$<>mbc"/7yV6`+ޛ#}V+ZC)q _i;mRma'>MP3]zyC b1Q#oMOpd@yF3"kO< ;vp I#p蕣x>L,|p3diA>#EZ348Nͯ|DXIFq ܎$r+'yO܊~?Z l|#_3HW@R#YX;"3>,B>>d*@Q ?7Tea6Kx&&k1o*:(!>.0/ReG"W̑% d1 X1_x¢5}5YZ^'ʍXm:ZG?8 t^WW ZuxÚIfc|QQ~g;r`q@sһa5Y3Qea7Ftwg jIEQpufa⬯ḱ/VG;$kZK%>|OY$>FLV~`UK"%#˪*lu >O(S5zx3=^I) }Swz%ě$øL6Y?7M ) =m%^7ziZ[Hq)D!(0I1ODrpwDZҼZoVmP*JI0%%q155I 7r%5 NN,b-?hFsn G G}Gp#bM CihnM ecK89)X/d8!Y J/e2@Y< Se!eYXU"k lo Md|{M_AYgLa|[R?V~S7։7(*y&,u!Y]91݈:JӬdAɸвp÷f>իnJSs8I Yа>[>`|X;>5=oҲm춹҂dbg[˲&2TsV3{ҕZe!&ͱ2൑9y&q-#ɂOTrAًԇ:.|,=l ]Dܕ$w&Q'!%5åUS9n7 zAFZpvq5o2-kp_HJ|S(g|]dӠ=%&`zVbS W+3k-NO >Ǯ8mopnP=^h Fx(1![g^G)}߽NxUE6w_TskF`K#oI @ϯ OQ?<ԙb3_Y/x??8eA;ert˿Oz+%+}J<Q楑endstream endobj 198 0 obj << /BBox [ 0 0 432 432 ] /FormType 1 /PTEX.FileName (./hexagon_binning-basic.pdf) /PTEX.InfoDict 18 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 20 0 R >> /ExtGState << >> /Font << /F2 19 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 19234 /Filter /FlateDecode >> stream xO4]Rϧ%,?U][XB敼@lwV߈< yFOo翗_<>mk&>_q'~ɭ~>~.v{/Q?W/o{7v{oO~o_? >_>/_T_~B}#ė<^~Wl>σ62ݦn\=麟?OW&V-Utx-WjO}\&V-U|ݶ;<_~깲%v}~6ce쇪p>ot~y]|6Rns[~%bjQ[\;WS]IjQ-֮k1rkWS{ō.Jny,v5W\E%n[Ԟ>=6ӭ_%bjQ[\n}4Wrkn{}7ZTWj_DL-*rhg8 +c?T]cb\N B%n[{Wwnf-T6ރtw.$5Ut^rKy vڳ$bjmt3ןK"IME°''{JƼL=]>~3$5U3=b{ynk"Jܢ{[v -Gl3V*qor HOO)یJܾ.]'b{znb15Ur-k}v5WrXO^/+'O{O-*啺ڵ_GmbRE+JnSJ7SɒHRny_w>=wEE+p=ݻzjQ+C&ԢۼM~twJE%nqσ'Ԣ[ʭ$bjQ[wA\1wrk%{jwJ[nR{{waRE%R{߿mMԢ~-WjOn_6Rn}nOXɭ޾MHTU!>[`OA Wn3V*q >X*m;X[-pkwxDLMnoRA6V']\SS%n=0*uݴ=ǚ sDLMEO؞$bjmtt~K"IMEO؞$bjmtt~k"n=['\15UZ?a{*7<'p69s{0v#cYꑚYw B%nA=n ]/SS%nJ<ܒ`PU5?r:uXYꁧ,$bjQ-~g \]קԢ8=SDZTtˎZjTE%nqM{Pߧ.$g&Snq[Amj1-:Ni%ݲ,փ>$bjQ[tpK"I-*eYn}IԢ[vzPۧDL-*qnڃ>uI$E5^_Y{\WkWr{"M-*wduٯV.ÚE#'ܴ}ꚈEE8˭O5ZTtˎZjTE%n/uړt׮+EEo˭u+6ZT6'bn]SnAa+ t[1tcRE'r${jQz>i͕4r{G/Wn2ݦJMo9m[_+c?Tmv-Zkփ Bnv+^15U-Zkbo:^DLMnxI$o:^DLMnxMT[pkM"^;F/۞ÚYwu`[3v۾#_ꑚW1zknv&SSn;˾^15Utzzj: Y[l{jSkfmgmY3v۾#_ꑚ:ݔ9^LqљM{u/$5U9ZnyzuϛDLMΜnګ~~I$zuϛDLM O`'BSS%n1Mvz0*q9nm2ӃITi_>syʽ>#~&SJܢ{]IjQ-rkyM"ݲ{-ڞ$bjQ[tp~K"I-roemݰM=YT<2ٽMY.$gv&Sn[Hmj1-OiG%f9zGVE}XȪZ{=Z{v,*AM{JwZTtZOiNEu9gemZM=YT<2M;Rߵ.$gv&SJܢvk]1gv&Sn[Hmj1nR{uX)Tspr˕SŸI%bj;CsfA6IÚYw>4&fIK=R3UטMPv2f䌋n:9iI$:Uy Ye,SkJLKpkL"JƼD7$T[KpkL"JƼD7$T[nnۂړ̆n멩5;әDLMO@m`O2 Jb:[L5&V*ӞNxG~x;{s#I?Yd'i6Utz֒HRn9+[e1-f%'%t{} YNX,*ʭMOv2ZTsBV|#5G&grkӓL"Ŵ7$Ԣ[+&;DL-*RnmSIԢrUmXqc9 ?~FZꑚE~o}zr5U'?azfQvRemӓL=YTsVBVÚEu9VemL=YTǝ9iU6{ÚE+䜴঳ϖDZTtIe3E^}tiȪzX;grʫm53bemS,M=YT{ YhJSkJLLtәϕK"IM=2悘͌v4fĄH7\&bj-&DΕ&SSe_]3OΗ&N;zX3U>KYۏ̪izf-C]{,mMTI~5*W>7YxÚYQd$QKVL=*y''(=,1*u N7%n,$5Uu$&娬{X6baTx$@Vfq}|ȿ'? 1v؈5Suq6aو5Sux2dUjRLɓr[DLM O7D)*k#nzX3U'\XaaTx\S O7zfKPn=X>a15U|2'H*{|bGjJLrk˭DLMŴ7=#XIj-3[`O$HTx΄nR{\mM$$؆&SS%}e6X"OpX8;-Mi'K"IMU<&UXaaTɑI2QnUXa15Udn*뾧iL 3zf&UXaaT;9ܔUx&bjk&UXaaT٬/=ctXbaTɫ\nJ:< YIj-F5aiIT[p )4dMTIٚ\9Ԟ+k\ 7y5`yAX)P[֦y;DLMU+kxV*kl֝IYuZkfbm󿩇5Se{ 'f{;zX3U>뮩=9*`Gj62`適5SuqM<{XaT٬;DPڸeL\͓"[ =DLM=2[8cfURLqL=*yMɀk"nsn}wKTn62`適5S$SrdU2RLՁ59@emdSk;ȪdӃ*uS*k#zX3UU' Xz`aTױN<{Xꑚ+drrkd:nFY xz#5Su܌4)Bem\SkJ^Ťָe&SSnA\%JI DbHGOM'1+|D*m/wͅ?MBl !<|k}i8g=E,L!iN:܏'NJzb-O5dYIP5>pSYђHRCA\~I=*=2ɘʭQ'KL"%r#ϖD*uKSnX:d15TUfUR 1ȏC Ϻy*k#?zX3T>K0Ozf|}q$穬X:daP$.NYy#5COA*kF-zX3T?zɿ=k>˃YdaPy\1!R'Ozf~z{c}vf帖5C%wɘɓHSCu|2ڨ%S ՁgdLȪɓ O<˃:Y2eaP7l$bju&%BVF--HPISnX:d15T-8ܔx:&bj&穬X:daPOSYtÚYwҮDȪȳ*=[F-DL Us J7F-*uKJTnYd15T2[Dן$bj-ѥS~[ ]+-T, Eif#n (ɳ%Y|9n֓H֒$RӨ3*ϱaeJݒH[cTcDL %S*F,2*NւH!2*ϱzf$*ƨ,2D nʨ& YfaP-OJ<[ꑚYdi5KL=*}'' 1ЖD*uKUnpY f15TNU,C3f|֝, Yy#5Cbrkt8jnt%J7-WjO I"J&n915Tn2WHSCZG}1e_5G&g)|lI$dU%\&SSUn2HWem1Skf}寙IV%g-HTx\UF,]3fl}T+9*9tmGjgG UF,]3flWcF,]3f<ɐUəkK=R3U6>6rf隩5SeddUrRLͺ'YfaTs'㘵3KL=*'邛/ǖD**nb<ۆ}9>aTwM҅ʾ<hTwՙ6e5SɐUəkk=UF,]3f|GMNVY9tÚ:&'CV%g-HT٬|6rf隩5SeɐUəkk=kRڸesLqdtQ;KL=&U'{K=R3U>&e+,3*u 7nͭ*qKVnY6g15U▔wl$bj-(ܔy6$T-upoRn>l i!9>K>7}$L7:oZkgU,C3fڒHRSe YfaTɑI7%\-$5UD$bjIY.KL=*92ɳ঄S%Jܒg[#\DLM%a*Ɯ,j +*3c6WFO15UJNL|Ӣr˿ {A U-|˙? H=y>hb-IS5dIT[&){|jI$*?6re閩5S%G&IS5dIT[&){|jI$N6d5SeT*{|jGjg}8dm-SkfISUF,2fl}T)9*tkGj/YtÚuINJeaTw5 Y=y>Ú:.9ISem)Sk;$M'˧L=:IUٓSK=R3UuSUF,2f'BV%Wnfl֗Cƽ,3f\'#YfaTS nʽ<[IjUF,Y3f$#R3ODLMep˕ړ_[~>ܓ=5*ebA>Ԝ[9Z-|p[KI]kfJܒ[[#YvDLM%y*Ƣ,2r{BV%Yv-HT٬/=YVfaTɫ nJ>V YEy^ÚY_z YÚYw~3Uem$.SkJ:I,%}L+Sem,*Skʟq> YEy^Ú:if,*Wks`XULqWIUYUK=R3U|'OvTn&Yd15U&;BVI8-HTLvTYMÚ:י쨲6d5S#hUi'NK=R3U6>쨲6d5S%?pSђHRSu8Qem4'Skf} 4dm4'SkJ^dGpSӒHRS%nɎʭ$KL"JƓctړp_}"IM&n]9ϛqX)Pf5ܓR_m"MMRwGVp)OLtk.R%J܂6'˨L"^fnA'˨L=*u'sY^yµ#5S%b*5ze IT#U'\K=R3U6Nb7X6ze 5Se{/X6ze 5Se*kGjf}gU!kWpzX3U*kGjs H6e5Set!kc_zX3Ucht1/ǖzfq}*kg_zX3UǝIUٗcI/L=㮯ɘUəkk=*u Y9tÚbW n}Y>f15Ux)4fURL`Upk.:njIVŬJ_Wnsn>DL-*[خ"b!vl1> /E Y>z.&aVH蓄:4Xt´SF85i)ecRfRS%J܂­1DM"܎zYÚ#nJ =\IjcFdmRJSkf}U K=R3U*1[c3DLM?2J 匦Lͺ󳳃22Dzfl֗+6h95S+ѕY!zθ#5Suq b!ZhaTsA 1DM=*\A UK=R3UB&+N)tU)'^d~(%LՁ5*p5Se]Q@K M=:Q@K M=U)'K=R3UQ@K M=*cVf#!kzX3UMI 1DM=*KR@O D*{d^:dmВBSkJLP;)oMT[P;5gYIT[P;5gYIT۠vtSYߒHRSEO]'WjOrOsRn*X]Ƒ8e~jǝ}cdmd+SkLr()jI$EEPȔW&SJ܂CMɔWK"I-*%*F,2ZTpju2i̚&VT >jneK#=2CetS˒HRS%nAQָe/&SSUnG=%XbaTɑ B7*,$5UnXzb15UuIEaV*,HT٬;?];( 6bً5Serڸe/LϺAQUg/K=R3U6> YÚwrP)WeI$GfKYWÚ:U XrcaTx\0ROnzfx%E)U{q*unJF<=45Uu7EAU,{1f&EaV*f{/&EAU,{1f%T{hH-Tt^3$p@.\nl l)?էth7Z0h+ xafQ-I5bIԢ[ғrk<2E%n?DS%ݒ[#"DL-:s zSzX3U6Kϩ0r .zf F,}0*q F,}0*:c7UɂK=R3U6>YÚYw=/YKxv#5Se6ڸeLՁ@Pdm\² SkJA!\³%}!FeTÑWkgI`̪TÓ^Lqg\dmLrSkg\2 )cMTwKXnbaTo$AD,71fU B7e",$5U njXa15U0U'k=*920֨%&SSu\YÚ#nD<7YIj-$bjm)dMT[|n= '*q F`,1*unJ`&SSUn?;z~dmSL=*ugcb`V!#5SuqY a Skf97YusRLՁ5&dm33L=k&;zX3UrՉyn:)eI$:Uy M)Lqb̪Rz=Z3UטV/v1fxA7@&bj- N)&SS%n11v0910~Xꑚ#=?`'RM?)*qnm IT[pkSL"JUpi՞wQKUM-Tm-V'o\R+p 3_m|F[mZ-n:)hI$EE} r$ӔRn[3&;DL-*}#5SW1r1]";{Mfw^5uC5fZ vB[45T6:^;&SCܾ;q^;k"JFB~$bjmt.tkwL"}w.⦽wD*uZw;w ݆Jݝn~o{ց Usk $@zj=ټ}"Q^(6ro/ cq^;K"I-*eRn ^&WtꖝK^;&SnK[.l-'hVSW6 rnd\Sny.vǶwց`> 7򚈩Eyn.Sny-vϵeE%nqs}yI$EE [/{WSb>ny*v_ _{$}ڝMڽ +*rI|iz[*UW ^L"JnzW%Jb.[NJ'k`OM nf&SSnjF7kHRSE[kKT۸Moij-P{k B%n1--SN+p[15U+*em B%}u+{~r)V>sB ʽ=yy݊[k`s&W-UtK+*k V-UtK+*DL-*;5^'U +*tJ L[t/pz=-pkN,$r$wJn-WjOѫmMԢ[tfp 7E%n{[Ԟ3ۚHRJ\r'Vtیaϔn}/JJS՞]Z[WW{dnՏ;JXj^˳'+p}0L" \=nq 6ը|sWS F7EyL~.%bjQ-ΥQf>+.Ggc?T]?'W[`Ot bmbn[ׯ]s(jOMpXvIykr+9M\D{uO)m=w-0ɕ閪r۷#~t:Կx;_osHsT[:>w?}9X~ޓ`}9qoĖendstream endobj 199 0 obj << /BBox [ 0 0 504 288 ] /FormType 1 /PTEX.FileName (./hexagon_binning-showcol.pdf) /PTEX.InfoDict 22 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 24 0 R >> /ExtGState << >> /Font << /F2 23 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 21 /Filter /FlateDecode >> stream x3TR0TR( a.,Eendstream endobj 200 0 obj << /Filter /FlateDecode /Length 1149 >> stream xڍVI6WVEcmo}qEӃb `[$'yZl% #q87eO&RkQXhy9/]djbӴ)NՋ?VQj$z%^xl%Fj[ݫ^oa)Ӫ8#[*~]"HV9(ADGo+]FҤcrnO,W>)i;G-F/74a/h{px@)-t4||WxNd$,o|#qc@gjFmyaX(#w\ X`2 0g:ar ʶEf^($DZ T<!C [$75/G$c1d aa/1 q&S f5JFqVYqtc <%7% WOTʧոMT}A^!6^xx kՈ5Hk&J a6EbjDcȍqD)y鉎nZzk /,e7qH2Q!Wu m/W'EnȜ^ͤK$ҪPO .tBVH)P}C6a*i~@9(j' J7#BAx sx˛Ȑ&FK 2(]L W(&Jb̌r| vj2Ͽ ܎!>BˡmV@ч(iDhȬFS@SgPyRJ ]>F@Va8QHH᪐zŰJ?)0<͒(nHIܒ2..\cF#\؟5t$N:2aA!c3#f92ь@?jTO?^!sEzƁ2U&1DT*&S)d^u U?gBn| lEAfHhF'^43*ݤM'$6ܶA[z&V<%5<A {p- V[/HF9oqIHH0^B[endstream endobj 201 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 202 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 203 0 obj << /Filter /FlateDecode /Length 2470 >> stream xڍYIE(*i;|hH o޿wn! jʭ,ofӤMaEk+ڼu&c'7] B%ظ0oyNzoB߀DNz54O~&/Ӧ,7sOˏޝ2`p8q(@(మW&y@^} Lh r݊3-zrLӼ,39yLQ4SZV$aeϊV@õs/f"dpe/~T,bo ,OY#eP"0tF $PUEWH_(6o\qgF*OMfx&E"خ9~jXz.߷@;tp΄Lt'B 8$#X mY;#ki Ԯ j̾=؝E/ܝcڞx10bD@\γ*9yb/HI4)ZŎ@%l'x 39< +Wy6# .mI PMI2pq䬕/2JU&q; +M@C>l c f W,!Sm -ؒ<|e@;wl'&,lm[yύ nad|nϸa;(ʵc>HIxɞs;L[ LÞ4rq`2` +xԣGIQs#|f8IA%(;,tj:FPLxXK> 96!$:u (&_SO6m̶ڃ[YΘ@u/U(@#i睭& ]<_0:NOhpSK*T':-No\r:E4Oiwu`Kr lKWZ aE$x?C'~5ҝ$Aq:ŴJj,#E ˲Lv%p r1y>S)LElqj!0%5&QJ'+lR/-׾[X`J_,tb9z9AT~?ZQyLO;dQ>Pj%1u3lzÇE 6;@rldqqYڴ)ʃrw '*H",}5FL+^f5b2zam s߈%R1u?wџ$F(p4ۨ.YV Z1+Q /1-TzfޑZR2bw%rL*4 [ĩ C|ɖJ:-"momI+e89inNyyeexL3"+4UP ]6IUn}FwI& +骈PLw,W*-noAHLqr`8~ZA+"E5.Q(ᩒNc^B27ZTeG '3_w FWr C]{SǸ***O CsVVK@yNcHSE^I ,㠙fx޻;nD2 ? .ü1E8 ]|i-BU8:[+l%T׼?[չY1_)&ϥ+uss|X ;6"Cw 5UjTBErL%yl\q}7gHoLZ͊I#^ T[F0(l&24* 1M`}nUg.Ob!7Mc+f_ǀm>9qŏ߅jh 5;" b&- *K1qfendstream endobj 204 0 obj << /BBox [ 0 0 576 288 ] /FormType 1 /PTEX.FileName (./hexagon_binning-showsmth.pdf) /PTEX.InfoDict 32 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 34 0 R >> /ExtGState << >> /Font << /F2 33 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 54865 /Filter /FlateDecode >> stream x͎J;OCiPi tI4i z׿Ze!9}kty 9O?=/u8?>O?sy|s/_߿~}_ܟy___ϟ} z|tGy1/q|~;>~>-Fl~~^OX4tpv>>𧹂s?>o~~_8XO!z|]^?;0Ž.|~Ipz?}\>+}z|x|_2w?YX>Mx2t>ݞ䉁"c~Y!Yd1 .?v_wr\/10q^N'H10hB>9|}.{9OlX}c<]Co 6_k!{:! m|6M^Exh%Dxws/rRT%JBt asj\^lRzD4Dz޻+C90V2b`&f\-ցIBvYR2b`f$jR !d|\J#b%{^x#!e8_?hʕf.EYB3S4s1v) H̅B#½]U1@,.cmR'YoP3@,.gn]5T>T)Y?&YCOX{]f sYl4z %[r{tmu= r{7F& {X?s )7gsg}cI<72KAMh%<.9}ZM|LS"7McjT-`ӻvET-(MrۦET-(a7)ՂMMoQUrw׮EQNr봷WUD ۣ]U JV 6ylWdȶIܓ v^U J>q\bl,󮈪sY]Ǻb{~p7b>Y.ߧ<90<8 OSB'ɣ󏛡.-b`$<9 2+VB%c乕[OWB'&ɣj%Dus`Cj`3iJ0\ajQuV ~.jT1Qʶɦwz?tETMŝl^mFU5vϥq_k9slg֍s:+P~.~RH~z-y%]U%l1+v.1^z=P ?tETMԁgh)ԪGu39c=%,Z-Fdul"[4sYj@lPo"> =^-N23!xb`$<1M݌ٔP+!ol˦Z ϘQ lP`s&,gnsƅV<г;9NeCςs&t3mWDՂ3i"CqX1NeCς:Zu|#uܵ5 g3.gV`;OET-(a[&bdI҅KUmdid늨ZPdǰ`i}J%l]i'HT J=9=1|UU l}{Os nUE USIX-b`$<&'Jy".MO.a5%JxFVD5=յP-!i|^ԯDf";2"L%|dг2y[h֥G< 3.Sj٬pxeN۫&]uET-(wd6ISkIN6]?z-&O1s>oUCς⧘9 l|ZLqLYSk]6?,(LY`YWDՂHY`YWDՂ"[VrfFU ll9Xd7GM-P`9ov65 El?*'|6xbmmIMMh%<&f<cpn' H7xJ3)+VBnhs))VB޻pRKTn\9$8dlcBqJ"TsϞ  ȁ`dcWDՂ"[&VFU z$9hl_CςrZ7fȁЪЧu9pj-ЦG㇞u99Z5gAwdV͕>{v?,kȩJ=z:"gϦHT y*SZr͒%bZĴywn5UUX*xIaF4h<&OIU&w|7Bg QTrWU"Z<RS]£hTdSB1Y:5T_mwHOԪyg:F֒lb3~(\֎kRR뵜.5?♨ρ^Ԫi'Z.DUlzQ5Qq)W%G&5+jgVMD>5u?z-jݵJ %Oe3Q)zblL.UD)ۚȦgx: |^;t'[dbulRuulވ=sguETMdLj% `21 4%E W%-Q{k< !Oɣ%ЦZ OSI] 2xvgԈSK@:%G#tgSB1F2kt[Y8iH(\gwCǂ:FV͕>{v?,kȩJ=zպ-KGV͕>{v?,( 絝ǺBJJ}r~YPǝA֒Jmr5~YPݿGVʹ>6?YP2BfZ{zq5Z2ͽ= iݘ#B&b,(#MO]U l ]F%lاflĬ2zU-(e~.nw.bx,N;J=xJw)=10xBܓG3KM ܃dpһj%dJ.Wr̚}2~A8j!wz%䰣9:tjvzQZ7eLЪ?ܲjqYOZKvgA26خw )Ղ:S̬ }B~"()nkzzCς:Jά=mWr;fֆG=MB~YP͊#kCoлG+9d+flYZ5}гDoл"r}ܓ jA [${i}+jA~[rd~]^D&[mbd%;_˟XlSZis! <'} D<]#hJdp<%I]<:?i=u൘`j-6U@xzݘ3Q^- U;ϣu<Z:=uL<j#g֍/ jgd2J(j-شa#`[Q#|f \ob(W0zBC'|nXPVZг֍;Zڈm,= i}ޟǥi?;Ԫm7e붶Zгxg{lOaQ=@ 9,lЪ}wzOaгG{Vs4?YPN^ZOгx%g{lOaQm}B{NU-(M`ˑ'.s`d%7"Ҙ%1)=-r'tB^MYL.7%Jy"rO.7%Jx2rMJJ;G*5^}SBx4"4OM.g7%J;q!&pһz%,:5}^_A9ےqfmhzCςrZ}ëɸX!%}ۄnгeQ4EkqyrŸgAY߷Z5}\-`q=dwzqV&dwW${V&uh}u![<žؽ\g"q~}=_m1یn5l}Evw_'O<\x^/ O '+)ȵ&mgs`$oSCςͶo(EVmC1u?z%'WGV;OCςb7ލ6.aE |As iK<6rәdԎZLA8r })!NoA6ׁ:%Ī "~PA8 ۸ӭЬ`ҍ )z jcA9ްl|~YPO&2J7(jA)fVm6t?,(u1ЪƷuq3fcۏCς:=ZgA9Dl|~YPLll1ZPecUo?͏xaqhfOCς:,)4^dCς=ll|iD--F'v6׵jAz2aˑs dKM 92,P쾶?mTsi}r_NleQOiTsu% D<ډ\kjJɳ.hNZSAXKTt"Ӛ:YɣDƦf%fVzOAXQ4!vS{z :S_m@yz&k->SkiC1?Lz5 ZqDxdVmC1u?r HԑU 3QVgj-m6&UZ75>׍iL=Yqti+z+9P͍L d3Qǥ}UېoL=e{Fچ|c~(9L҆lc2(e6mC1uETM=К#BkmbZWtw\ Vn69 rR:FSBLOʢ0L \h>r3P:ĪM+JAXV/lL>\?i>) \b({Dv}ӊJ9v1QV뮧HԪZ Ski]?LoR`~WDD [VFUe?]vV>7?(/m'j~CD7>nCD7_}o~3Q%աUӻO=%WrfVһMFUe̮+QfLb{bqm&lEmfOn33w_[gܗ)Of&Oi Kă(D1<\hJD<]hJs7ʒM>ro˃J TrǓԬ@A8]!S%z%)tjG=zQrZlЪey2#aгplrλjA#yE hՆ[Hs-@weW=M~YPNFOl1~^JN>o:LCς:NmZ<ꕜFOl1~YPeFU0= idZгx762J?(jA [i?+jAaדhg,к>61⑹^{MHT M&J}7rӻͻE |A;%Oɣm!]s`$rϓ(ԮL!Ng<6\iJ{4v}gʬ]ԑ^:7 ԞH~Zw}ˇZg.3Q~* Ez&ʟ~wµ\g.g<UP Ek$3|~(n+k3l1~^>(óUQ|E"&]yZg.<(uU@k?L| ȦM:.CeVt?Lպo'Ak?L|*Ȧ=wR)OUMųӠ'iPJDJ۸N>/1! 'y`Lm4%J{/ʂ1UjpSBp4" LJDE<\hJw|3*1N|)!8#]'b(W0z"C}#nXPV\UӾo= iUd}zϷL`Ӽ3}WDՂrGfct}~YP<2'[I6ET-LЪygG< i;#Cuz?ד$nʍ"E&nʛ"Q-(9zA}*~YPN߱%qTnг)f&nʛ"Q-(a| 6M>wET-(a[G-F'v jA1QG}|ސ۸||Ac&Yxj%da,iN q*y,v!N q*|*5K|)!8FnD5IݵP-!xlMdfv~n|6Z5Eг fl%۬lQܑS23C뵜.i7?YPSܖ#3Chk mO^*.u9{j-tUDw\3qC^7&w?,סUOϣegmGEڟZKgAyl}ZPeסUO= iaj-v㇞O1>4Qc=g9 f4v#-bB^KZ5ɣvs`$<'jj%dnʒM>r[=UjvɻSB=ЀJ.7tJS1G2kw[Y8~SjcAzl}bZPds7?YPN붬Z5OгKQ#=O%Omг;UӸO͏x|bl,E|gS!ń'/y۸@rȹ*C|) V5UaZFAL#G[ UhM B?Tj p=S@m#OН+ hyA}G^/QV'Ԫ7:FӀ=l?1~(\|sZqDxDӠVt?r Hպ=tOz&U4 h-UZuGICDqV̦A6tEz%긤MZKg֍fmԪO1ٴ=Q5Qil%ێ`Q5Ql%^:!ۊ"[*>q}}Z-bBˡg\wSB'dsSB EL%W})!8'&cj%<d'&[}j%m3Mf!Z|UoDRʹ>v7t,(un&XhLsoCςZHSkɴ6?,(\#MSO]U 62(j*ɵgAwudZK*gAwudVM>6?YPHЪuܽ<Z2ͽ= WrfPi*ɵ)ՂrGfjLsoCς:,;DlSCς:ƳjCKճxSDܻo2~o4ȁ>YB|<]֌?&O@QxllsWB -]>)!N嶮1|\{A8}d!rܻz%ܖ#C&rګ+(\#AM3]U l'[I69ET-(9llrLsw#enʐU3ϵ\u Z_5gAw=Lmsbxudۣ&9wET-(a 6͵>vEz-&ypdੵbzӺoZ5г)fZ}"2NLmz5ZP9lL}z튨ZPLFW6&+">佫nɣX֞[ Dv?Lԁ@fPhTkCDx\3N%j3Q3 6M>6E?LЪ: vj-^㇞:n Z5g}Ъا#d+ئfRȿ`DSsS$$K۸<.cyw#NM.6% y2VMJx9y4oDZV@&APiNrմiiB1FNM>V/(=* Yɮv="&~vz-K͏x&ʟ3nd;hմas-R q7#Ml.iz'!4xJ2i90x2xZJR.m5tJFɣIeZ qGc۽#3ӐYSKZ m-(SZwCǂrZwtR7zպ-[EZZK~gAy l|J늨ZPlLrUOi= G&d+ ̦4%l符HT J"MSOJ]U Lf zqwLLЪG< b&&i9+jA-#ӡKuUm]#[=R]S$%lgȮ?sCV2K1!ӥ}S2Kl9䉁&^VVBs,jjWB'4fU"Z rc9d$jjwBv4GNM>V/WP8FjH5"2MmZ4ZPsط rֺgAwngjV͑>kv?rqwfNh}s$3.3d+)&UUD ۣ^M%Q;g2sBPTG#qiQDՂH`fWDՂH`fWDՂ"[Vr͚FU J"5MsϚ]U m@-C0qIXsӕS2IM] 2yv5Z@f F45\!Vu) E%*F$jF9c3P&z&yZK±)g`Y]UU^ )󑟳"JrleFQgɊ*lqOޥQϤlyOl.mFUUآ1-FU5PʖVN^ LwǸ]?W{_΁Kr;V.Z'Dxl{T)\q]f ۧ[`OzET rET Ta%]Ulk~%[=0r) lzGwRMrGw=*lq])@)[޿&[ٻޚe^o˟'͑_zȭ=B)l:Rr1@ [\`_KM};rjA 7GK`늨ZPd+~{OEz$J^}Գ$Gn*[^\5ZPd[SrdIȭTeYӷd]ywy_vT4AUܮE'[*kQ-AUܮ%lq MJvET-(58Ui\%l1Ã-F~U-x='"2L{O`d%Ju}|-{Fu[NypIH=bLD [\`+Wj"&JlzE)D)۫~fב^sl+JbN[RsOr3{-Pz]s -FbzΚm\ۿoȥg?ۺj[=݇hCql8`ӣ?E׀-G'GEr; S^[&Fw^Vm?F#-QGlzgQȖc p.=mbƲUV4yz0S~'&]*{3 ۬#~\hzs߱UU[r?]z[=ŕMw~˿˃Y_}}_篿/_~>}߾j_Θe]~_~e1t_r$__`ϻ?Oy'~>9Y;yߎG?ur|2~ۿ_~?vr']x}!^7ܮ)x}.o}-+"T>5N|ɮNNg/M^| \`3jgOr_^~ܞItܑM?}wA-N uz_]́粴Q߯|yYby<{j&Y^OSB:s/L%\du`yw<10?Ӕ@+ r[{l|uɣZQZȳgV@'>ɣoKPY!}] <ץg{iΦ|֏ܕ~}z6́>gh?媄Z !Oɣ} yPN=w%Jx.?e{>{2s/c샐KsYs]ӕ@+!๾{<90r|.N'Ye.IrSqwQ;~->>ySPG=U <.<gV@ɓ7WwYެӔ@+ ³sҝ->Y!9#=kjDy>@7EW:V@|[O}qmYW샐lsҞM "GYreuB^mSxdXSy^O `/qlYB&΅v|:0yB&΅nJY>\hg˦Z u̅vlJ7x\hfKZ u̅v,JD+!³N}ΖM "< lٔ@+!䉩o\fˮZ u̅vlJY>\hg˦Z !OL}GB7[v%JSxd.eS:GB;[6%Jyb<:ٲ+VB< gv3+|N2- 0hfJC;c61 R?ߴ:|// lj=S|{sCϴ.T2(P/0Jҹޥ.z)T]d.T2LP/03 L641 P,2d`P/03 L641 LB%M TtO* ."t1 LB%*FS>PI A^`jIIe.z)T_$ ظPň^` g*6141 Lz%$P/0JfRi*p^` BH!b(U/0ejjv>>E&F>mCYl:]))Ղ3ջ" 6QȖd+ۍ"D 6Q-jg1]:I)jA [`9UŤ 6TQ-mLgE'[oQ-fo|%l1Mt?wET-(>ʬng~%l1M'v?wET-(al:+jA-'Vw"|6} hDxWU{~s s,){`.;`GPV`ˑɂuET-(a/ [|7FNWDՂ"[fVҋM8%Oad%J"MӋO8]U J"MӋO8]U lU&[I/6ET-(a6M/>4EZPYl^|銨ZPYl^|銨ZP`YeSDՂ*`NWDՂ*`NWDՂ"[fVҋM8FU J"MӋO8MEVp"2L^l1ZPYl^|iD- 4Q- 4QȖYebQDՂ}2+\M/>Sl#5T:pyl%؄cQ5QYl^|iD5Q+F`쉹婪(ad4JVy(j-4+<j-4+<Q5Ql|ꊨ(ad4JVy(j-4+<Q5Ql|ꊨɶ\5֤ҘCDȌ\6MZ>UE({d6IʠUsr=G&R4,Q5Q–lfQDD)[2iNY+j-R4,Q5Q–lfQDD)[2iNY+j-R4,Q5Q–lfQDD)[-F$XUlϟE![`Opl]U%Ofsک }rԜsD/g'[I69ETMEB"&J"MSO]U%l'[I69ETMEB"&J"MSO]U%l'[I69ETMEB"QMEB"&jM#BBz&GfdVSKNUlgRHq`\_WDD [Vr~FUlgHTlg϶pj-&G㇞#l }rlD5Ql }r슨(e 6M>9vETMel%hQ5Ql }r슨(eYsb{bu9&JfLi벹ϩ*,[_<d+T%l'Gͩl"[fVRMFU J"MSOMEB"EB"2N mr4ZPmދ )}~YPrd"MSO]U l# ]rtZPl }rTܧ~_ǿ?]>c])V͔>wv?,Б?UO= uj-yf^㇞3.+4Q3BYyzӺ1GZKgAS 6M>1wET-(a 6M>1wET-(el% lQ-/4 jA [d_i+jA k͇`9ZPd]Nwrdv^JuET-(c# 61?11P/S׵vim+jA-W'[=IqݣE ="E ="ٲEL+l0ZP-l+|芨ZP-l+|芨ZPmc2VbCς6{4EZP-l+|芨ZPsؔ5GVm%t?,(A[m%8ET-(a6{tET-(a6m=tET-(el%oQ-<4jA [dqi: +jAvY|j-&x㇞nl$U͏x?L`lWDՂH`lWDՂ"[&VFU J"ɃM]U J"ɃM]U l'[6ET-(a-mMbdIZkU#D-S<È|׶~z_?gl%oQ5QIl}oD5QIl}(a$?J(j-<4j-<4Q5QmwG$}~(92'[6ETM=2S{hfCCD鑉$6>wETMFl5ۻQ5Qsa9SЪG=G&zشQ5Q=l |{芨㮇"+l0~(92"wR`fCWDDw=`j-㇞Z7hЪwO1[شWQ5Q–-b^aQDD)[iݣ)D)[iݣ+j-ZشWQ5Q–-b^aQDDiS0Q 6H&mi+j-64{|Q5Q–I{mQDD)[$mi+j& IZ5{|3Qrd2iOm>7({d6fHЪG<enʹ#C&wz&J?`}WDDm$VNU?s|g9g߈}~(=2ݧLړdoύ"&ath}#:>3R>jݠgS̜>Jr(jFNVM>7?(uc[}7~(#Ms]U%l'[ETME~ "&J"Ms]U%l'[ETMfH%Or+ ~X>q ~ "Q-(a6tET-(eʟl%n`Q-R>4njA !R>jݠgAɑ6tET-(wd6HSk?,(uc}7~YPV떌=:jk͢gAaSDՂrG~>wrdijk͢Qς#l|芨ZPl|芨ZP#L5faгGGVm Yt?,a@vKzahSk?,(^7Ʀ Zs^гxdaL9l/1ZP l9|/iD-شs^Q-شs^QU#sOҦ\ %l],9M4ET-(lOHV\N~s lOeQ-شOQ-شOQȖi>e;QDՂ?`F[SWDՂlN'h>;WCςrZ7vhOSkSs?,(~ȷHT m*j#gA9hOЪ}weڮeўڧ\r~YP8F{)߹"E{)߹"ٲL҈lk2ZP]M@6"ߚ,@6"ߚzas?SkiD5?,(u,h>;W#ū#شQܑ=A)߹zLV\FU Jآ=M\]U Jآ=M\]U lٞ&[SsET-(a6Ss5EZPzgM5ZP]@;r+۹JÛ#~ўȦ}wHTlk{")߹"&Jآ=)۹"&JD6Ss5Ev9j>;WCDYzY'j>;WCDyۚڽ1،z&JθhOd>;WWDD#d{VSsu?Lx}76ڧ\r~(qc}G|c~3QG׵Qv9z&5{jmgx%gs[rETM?2&GsVru?LqlnԪ]Z7׵Akr?Lq!{jmgF6ruETM=2k>h-MжE㇞#l}[lD5Qʶ>im+jm}d&bWDD [>&hۢQDD)ȦMзŮxK5{Hl<{*z61ُn;Er{z-_%li-7 )ɖ(el&lQ-:-ش&Q-:-ش&QȖvkQDՂlrtZhՖpCςrZw=qVm w?,(uWh--6a㇞enkшU;͏xӺkG#VȾGw?,(uS'Z#гm];Z;= i}CxEk~Z#г<шU;= u驵4lzfшHT u D#VȾGw?,O#mгG#VȾG7?YP<M;]U \61jG=gA9OOanг)f6l»"E6l»"ٲOOҰm 7ZP}lڰ} oD؊O?#okG~X&d> 6mؾwET-(=. l92$kWՂh`>;;M-Pd>J(jA [wi)Ղh`>;WDՂ"[VFU j_}o~ij֍ޡU= iZг]Om7~YPNuhЪ}wn\}~YPV}h}u~燞>Ҏkqy_Z_gA9?߷jgAx\Cyzqkv㇞u}`thbгW zaSkY += 2VUzCCςBlW "a tt㇞n\hյgAS̕Z_o芨ZP&3t-7tET-(d+k v(jA [WIFU-(YCwb+ޠGPw&[YK FU Jآ˃M۽_LD-d+ޮET-(a.6m~+jA [tyi+]U l'[ET-vػ ЪwnơU= jOoг֍=?8j?ςrZ7hЪwnz>8j?gA9sszz?{Z~\UVw?,(G6l»"qb驵4lzaWЪ ۷G< 갻Ъ ۷eޫ>=m[Cς:lF}ZagA9WCszanqh~;|Cς2d+ ۶pUhЪw%G&8شQȖm|~n;QDՂh`~;|S$NVUk#~z-={jm}glخ%RMWAWDD [tb`Q5Qʶvj_1hD5Qʶvj_1芨ɶ+ZzCDɑO6] +M&]o:PZ*DV] +=enjkֲ`W z&j3?j_1~(uӓԪ~Šg֍ kZj[1p~(3B@W Lzֺs@z&wdbQ5Qq㇞WSwm+ kV] +=u,Zj]10~(u UWACDS:.`3QV7UzC#yMzCWDD)ۺr@6]K ]U%lr`"&JZNܖwr+ްimbA#-r``Q-Vk ~)ՂX9%%lr6]K ]U lr0Z]o0ZP+`ӵQ5\9V]K = G&W&[YK FU krzӺ jյг=oe@kYK = iC@%G< iݸ&+Ъk ~gA9+Ъk ~gA9{~ u-78?,(~z_Azcl"=6,ZzCς:J+Ъk ~ςwmKhյгmȕ%㇞u,9VUzC#uXR+Ъk ~gAwZ_o~YPCfle5ET-(wdvAzl2QȖ+%%l_ [=1mbd%lLɖ#ϚQr\|$~|Oɖ\ %lN6]]U JblrW7"rb aQ-)+~u)ՂXi=5{dj-+vugA9W@bZu¯n4?YPNXV]= j ʅ_~YPN:ZV.CςrZArW7zӺXV]= iݸCk]p= jݶЪ+~uQς:*꺇_~YP|fNr@{ennRrLeî?,(u'Ъ~mgAvЪ~mgA6oU{ص㇞uXЪ~mgA *꺇_~YPeF2UbгB*tï4EZPl\5hUг tįtET-('-Gd=ȭTՂXu%l"6]8]U lwKy4GdɭUՂXGxG³[]g?DI,RXG,ՇlWz&jݸBSkYY=en\uhՕ3Q^XGV]Y=enK#Lee>?Lպ}hՕg}@,ՇZ7ӱWz&jݸBCk]Yp=řgMAWDD#m=$VUACDɑ.?J+FUm+U۽_h~3QmE#:ZZm= 9ytNhjCς:,Y B}S~YP%Xam5~YPN.ZgAnla}튨ZPla}튨ZPd:J=(jA [4Vi=+jAI_y_6IVy~XbJy& 6myvET-(a6텾;vET-v3驵BzӺ4jͳgAS6텾;vET-(wdulSk酶;?,(uc }wl~ij֍]8Z j/ݱgA9p@h^cCςrZ7vCkmy:?,(\ɣM{]U JآM{]U sfBzպ_F V텾;6?YP_F V텾;v?,ǣNhгF V텾;6?YPV'ЪwuX -Zг֍2ZZz= wl`^cWDՂh`^cWDՂ"[VzFU JآM{Mth?ˇ,Zc+*~Zėg`^cS$%lwǮEq4;"`fA6;,(uc }w~YPN7BBzӺ hSk酶;?,(uO }w~YPNߟ-Zг}Z ]wt~YPn`!U[oՏzԁ5(j'gAx\BvR[zlFn4ЩtR[zn@U;= 갹`4PhN{kCςsn tj-V㇞uXv Zг˄BvR[z萓J<";2BvR[,(92@֮%l@֮EltR["sYض]K%msme'%ϑu?D1J6vETM lI}o튨vԓZh-V㇞#l*}슨({dv}ZU3Q^'ZZm=enlkVmy6?(uc^;$jͳg֍MzԪ7╜-p^躣SDD#-Z3QzdG6mvuETM?5ĵAkiv?LolkkVmv5?♨qUo=uܑ=ZKgQ6;Lq*{jg=l|늨({dv=kl3~(92ȦηRǑMo]U%lVmFUlk#6;"QMhV.O?s+ǴaAݖO?ɦ]EF%ۨ"`;'j}ςrZw=VZu?,(MےoT]U mm6ZڒmT= jfA%ߨzӺFЪm7n{0Zc= WF`ӶUU̶@YAv-Ǻz7ulVЪ]u1Zc= j٢YAv-ǺzawѬUc= WrvVڒmTFU 0j[gAFVZu?,(~ٍ&[iKQET-(wdv=CVZ5?YPrdYMc]U JآYMc]U l٬&[ZET-(iQѬާUV3M|#\'0ٴk>Q-شk>QȖhdQDՂlbt#hնUCς#lږ|ꊨZPlٍҖl2~YPNƆZ-FgAYbt#hնUCςrZ7>nږ|~YPV림jh]1燞+yt#i[+jA [i+jAvΌv3c;Cς:ZZNgAS~6m,tET-LNdгxdMo5Maah[MCςrZul7Ъ}wO1d+Ŷ%lOŷ%lOŷ%y=饿5=#mbAol!|hD-شCQȖaa{QDՂ`BS$57h Ъ%G&2?شQܑ|"Oئ`г֍'2?j MgAYۚOd~hBCς7R`9e}̶̜ZPgAɑ6m)tET-ΙU[o = G&Sd+9f}%l9gu}fvh~Cς:=2ZZm = Yxd~hBCςl}ZPl|j--6㇞#l|ShD-2?شQ--F'KjAI_3;>9JleB%sdQ?%Dsi M+jmdBWDD [d~`QDD)ۚɦ9gl˚U[o =%G&R;JY(j]N}o~3QVvj~CD駸viY+jٖz>ﲾCDdj'x"&JM6M>wETMqghvh-9f}㇞#l}oD5Qʶnii+je֒mZ7~虨ԪIܧG<%bnii+j4Z53Qrd"w$q֍"&JM6M>wETMl}Z(aOaOTDiƎ;]~GneA<61ُ!gdAS$%lwEL~ "E~ "Q-(a6M>wET-DʇVt?,(铭$w"Efoϻ"6vЪݧnKӇ֚]w~YPGN&w"U-(a6M>wET-(a 6>wET-Бӧ֒m7~YP<2ݧ%l󮈪u{$doύzL&mi+jA#1G҆V>w?,(Lړdoύ"Efoϛ"Q-(a 6>wET-(a 6>wET-(Lڏe͑zܰM|#g~>d+s%l󮈪%l󮈪ELړdoύ"Efoϻ"EVg"`2iO%{|nгxd2iMMEVg"66Ъ'#3`%l~IZ5{|гGNVM>w?,îӧ֒m7~YP<2MOMEN&w"2iOm>7ZPIl}>oD91G҆V>w?,(92󮈪ELړdoύ"Efoϻ"Efoϻ"$ȾP,M%c)Qp Ⱦ`4sS$RȾ`4sWDD [fVҰMFUl}i'HTl}i'殈RH`<3oWDDM>ZҰM=%G&/4 Q5Qlg}튨(9lL}֚]bv~(^ygުHUl?ԧ֮:zZ53Qrd2NHmj5(e 6M>vETME&RZ"&J2NHmj5({mL?UOkg+%}  H Z1Jf|ۭV}P֎n3d3SW'ܜHsjDJn3.-HM*͉4F$jVnN9v"RSW #y\[e49d׉HMfF[n[j.*UFS[NvT٭2ܜrDJn3e--wlHMr?kVFS[NvmL_hpsjɮ*UʂsWfTHY۞R6KD*LԖ]3SWRܜr6DqGF[[j.Ù+33ܜrkDnԖ]'"5UdXsa3SLx`u˹ͣzZN9Uy83Uz|7'Ɯ*;̇mK1U"RSeʇpsb̩*gJlO/;ί9ϩܞG_|mm.@DjV np95"QK%Jlps9Z*Ub3\yRmf嶥[e.9։H-*s),'NDj7V=åR92ܜrRۉL-*s),'NDjV nQ9ku"RKEۖb DJnV'"T}.7V稜#x&vjx̜_}UNW##ʷܜrDn3'--9tH-*')NDjV9 nNN9]u"RKEۖb DJnU#Tr7':[%9|ԉH-܎s'DDje$:9tR%sa,:wlRwq官[,9wlֈD-*')NDj6srےSLWRɭrܜrjDJnU'"Tr7':ImKN1]"RK%IpsrZ*e[ryo_ށWtuw"SSeq[>;8-TɭN3m[<8-TmftNDjVܶ-TmftNDj|O_O%x'|*Hv 7D nwᶟHDJn7؉L-;n>9щH-;n>9щH-wr΀xN"RK%π|Nt"RK%π|Nt"RKQB}U^w.=UCyOR'"5Ut;ާn/mVSݝTmO΍@DjVSݍHT٭ާp;7;ۼ|SSeVgrDz<}_o~wPzLR~u"RS%Yn{)[^ͿPm^.w7tGmzT]R?~w;79ܶDn]nOwYnS%zu;4"QKuӯ9yR%_^{Jz?x/\~ą_/~??ޮs=yoW??|?./?_wwe_߿F.wN_.S\S??_O_ogˏշޯzt9~ޞoO~9]CM6ur\5L9}]q|?}+z^zg<E| X!Y>n4| X!ܣֳ\o}x` |^ok6x_O#+$yn~3Xr/ | Y!xk^^ K}Wn偟g5J|7m$b>W⻩|_Yڍ[p=ߵ׿ʯ,!x Gm$`D>\>~Owm'+$ݱBBV~wίܞ˵u[#:|ޏg~h$`D>?׻>< wJ }[j{,~^3'b<|J"-}FVJSRc黰o){,~$dD>(G'FnX)_dDQ@}[wWnA{>Mw%HJ|!><Ч̣Φpzmz`D>(Φxzm$bD>(Φxz5R"qGgS< X)uszς6+%G|tSr'!+%G|tS#>:)HJ }[>>)IJ|Ƒl$`D8~񻟁V!|E=p{H~n%|#>:)H }Ƒl$`D>Mzς=+$G+|tx\|x` }zlgm8 X!8Zᣳ6ƍgYOFVH3V謍q#+$uMq'+$G+|tӸ>:kiH |h]>>kiI } 4I Ϸq^'t}]b:ki>:kiH } 4n$`D>?/z`= opo s)T?: X!ϸ*ࣻ#.g^vw%>;>;H }Uvi$`D>uU,v$`>㪀x$d>㪀x4BbqUGwG] X!O]wG]: X!ys9>J9>u ?>?sPqa|>=ӧXy;i$`D>׃>]~|: X)O]}wa-}+OI3>.e#+%W|t۲շ||۲> m> mHJ|݅l$`>;|0ܖg\}]oFVJ3>.e#+%W|t۲շ||۲> mHJ|݅l$`>u-߅$`D>HzVX)yPWwn?WnAc;>WnNVJ3X΍NBVJyY RBʗtWWOI3rnNBVJ3rn#+%W9|tۿU||ۿ>HJ|Uo$`>*?|=g\oDg\oFVJ3rn#+%|nO'+%W9|t'!+%W9|tۿ>HJ }*_>IJ|nH|TBX)3"[BDo_q{7auK RI[@+G6: y٬nAVJ1o4BY}=}=(D[}]쫬#x_׿]ï=@٬>^lu{OtZj0f/Y)` FCYmlV&+岘 y٬nALVf15Bcht[!/4-J-FFlVD&+e y٬nLVi15B#eڒZrlVh&+ y٬nLVk15BYbk0V#ʩ-C^h6[L[v lV&+e ykr|KÐd3#^h6ǂeu{OH ͖+_w.<'J<2$Uo3xXmKq1"RK%mpsaZ*Ur\{RmŹ>(zdM*͉.NDjVnu9u"RKEۖb DJnh_#Tr,7;[99؉H-f[n[Ƌ90Z*Uc^RɭrܜrD nG;a""Trt7罜 w"SK% xps˱Z*UƃS_NRmƼ[%=9|؈D-*/GNDjVynN9%v"RKEcP DJnb'"Tr3tGL)R񜜩C+dE'S'\n[Y1Z*Uꃛs`ΊRɭ֙pGLL)Rmf嶥ΘL[eL9udڈD-*cͩ3'NDjVnN9v"RKE1ۖ:c2 DJn1ԙi'"Tr 7ΜL;̘mK1"RK%ʘpsɴZ*UƄSgNRɭ2&ܜ:s2D nG<ԙi""Tr 7ΜL;[eL9udډH-*cͩ3'NDj63rRgLRɭ2&ܜ:s2DJn1ԙi'"Ttsm3&@DjVnN96"QK%ʘpsɴZ*eJ}o|mC?GڳLyAP9؈D-*90gNDjVn΁9+v"RKEۖcV DJnb'"Tr7;L}mˁ1+"RK%J}psYZ*Uꃛs`ΊRɭRܜsVDn3--ƬH-*90gNDjVn΁9+v"RK#n{LY1Z*Uꃛs`Ί;[>9؉H-*90gNDj6Srr`̊RɭRܜsVlDJnb'"Tr7;L}mˁ1+"RK%J}psYZ*զn 7%ӝZ*1_.qŻodZV|xd<U7#+cmK1"RSe1ԙi'"5UvnN9v"RS%ʘpRgLTmdL9udڈDMFƤSgNTmdL9udډHM*cmK1"RSe1ԙi'"5UvnN9v"RS%ʘpRgLT-7ׯ?WB%3kεmL_P̚sm'"5U9#W%oN}L_o۞xS*NDn#͉7NDj6-ݜxs*Dn#͉7NDjVn[⍩8*|K7'ޜ;ȷtsͩ*Uۖxc*Dn#͉7F$j6-ݜxs*Dn-Y>e*ʷoO2ϯxx'NDjVnN9w"RKEݗۖcDJn4#Tr7;[ew9߉H-fv_n[?Z*Uv|NRn`uωÙ+3r|LRɭ;ܜsoDJn4'"Twr~/o{ R9w[% ЉH-þV76#x&6ԤvjxUKy}3Ӧj)pzK6TmnӉHMFK{K6TɭZ ܶM "5Uv-n-4"QSeRޒM'"5Uv-n-t"RS?u-ۄy83Uzeͽ%wNDj+sT![OnF}L^j)pzK6TmnӈDMU}x܌ߗn/f8:Yzr3pfʌC7܌:8mo=%"RSeq֓Q'"5U LWy83U~eFǡ[OnFT=Ğ [g*Ù+Snn=u"RS_Mo4$3^T镩3^HMFC;SUHTm4$3^ՉHMFC;SUTɭܶ{U "5Uv nLWu"RSPc+n1l ܞGgOtsMZ*Ug[Ln:Rɭ: brDn,ĦH-ܪ-&7NDjVnn1t"RKu߆,֭ĦR񕙝nn14"QK^m: Xbrpf0X݁rOpf8r:PIRW)Wf٥(>gJL5ԉH-܎s(DDjVn@'DaG;PI},Ι/ *>g,ŞH-/ *6f*gndu-Ùb%AՉH-f_Zn[-+Z*U_TnYRɭܠrDn/-AŖH-ܪ/ *F$j6n0uZ*Kp?_[y?B 77ܲ:[%AՉH-f_Zn[-+Z*U_TnYHRɭܠrDp;V7ܲىH-U|eNu ꮘd3KXOꕋuky8T[ysNi6R7{%4sD nGgʯhtsgϽ*͎֝y""5U{ΎMV50w`v"o0ga7ϱYf$nOg*ޱ6QYV&nnܶL"RK%[DJn2ysӉH-fm[ DJn2ysӈD-j7oeZ*nM'"Tt;me&ZN`Ly8Tzej7UZʜen{{ pf"]*yR%֓ڢ{{pfϤ- XWɻ>g*en{{ pfɝGmQJ޽y8T%6헷{{pfpB{mߌI""T]< `f$oOyg'܃,m3'RW6(`^%^gq܊,}Ov)iLUf=[zOw)}LU>Vޓ]J3Ss!$yT{nhlEI.%ÙyOߐ{KpfVޓ]J3SCVoY&ͣb;y˒71TmT-Kt"RS%کm۲ML "5Uv;y˒71Tm|Rn<GiSS%ˉ330LNDj6O ͯ[ ~M=r{><'m)Z*վn -S'"Tr}ܼA[NDj6Em -S "Tr}ܼA[F$jV"yLRɭEp)o:,mDRnYA[>g*Dվ -S3KXX R2y8T}XA[6f*Us_VoÙJ6Qs_VoÙJ'7Q/Z)n7Z*ն n?U'"Trmܼ;NDj6Mm?U "Trmܼ;NDjV&ywTRmn۶;@Dj}~ ?UG3KXOjVÙJXsVÙw}kn pf}OyGR%smnSQy8TMu?U3KXOjVͣXmOyGR"yLR=w)mgaepf}b6HqR4?6>p(JɽW R2y8Tzej_7oZ*}r6HqH-j_7oZ*վn -S'"Ttm)Z*=}gnoHRi[S٦o}yx?G]߂7HyԉHMj_7o*}r6HqHMj_7o*վn -S'"5Uv}ܼA[NDj-mLaLUd=}XA[>g*Dվ -S3SYmj_X R2y83U&E`)og*}/Z)nX{>gqƱw@yOT=<>6>u=Q3Sﹻ>Vͣz\96>`(gJ7eDJns_ܶ R2"RSeejDn/7HyԉHMj_7o*}r6HqHM5Sy.[)Uy=UGn?R,yӉHMNem[ DnS,yӉHMj7oY&*ͭr$qHMr{ԧ=Iޥy43UO){Kpf"]R"$yTE֓ۮ"uۓ]J3SYOmڊ{Kpf"]R"$yTEֻ>mOw)aLUdSJd$RDVoY&Ù+S;y˒71TmT۶e@DjV;y˒71T٭v*p%ob:ܩ,m71TyR;벅_71s;zmOw)a,Ub8d$Rg 7ϱ9=Iڥ$"RKc+VI.e3Kc+VI.Ù=?Kޓ]J3KO3c+X=Iܥy8T$Y'ɻ>ga؊{Kpfbݶ,qR%ֻ>CVoY&Ù3w*p%ob:ܩ,m71Rɭv*p%ob[T-Kt"RK%ک[DJr|]/=}c|Gn#l ܼȻNDj6m{H "Tr-ܼȻNDjV[yw#Rmn9۶@Dj}{HG3KXl XȻ>g*zw#},Ub5u{H3KY @d#Fgaֱ#Y$nVgaؑ[Ypfbݶ&qR[yw#HRWO[YpfԎnޚJ'"Tt;mMf%Z*ՎnޚJ'"Tr ܼ5ɛNDj+_Ͽ֧W۶Lj@DjV[ ywHT٭p#::[m-=Fut"RS%wXn&"n+Zn Xۊ>g*z}LUd+uDmE3SYwMDVy43UGDmE3SYOn_jVo"Ù'/wX&"n+gq 8X@y83U{z7}LU>jVÙջ?pfunPź Ùz\86`n 6u A3SYOjVͣb?6pn :[m@t"RS% Xnn [m@t"RSeͻ?D='WF=Tgts[ύZ*U7znRm:IFR%ֻ>@Vga`ucέÙ 9r:oŁRWՍ9>gJLc1V݉H-f?^n[c:Z*U?snՍHRɭ1ܘsDJ*,gk#{R>ܘsDJnՏƜ[u'"Ttxm9@DjV n7"QKu՝7>g*`uͽÙJ'{~5źu؋g*.֭^REs=.Xys/nhfɞ_n̹Uy8TVOVgJՏ5تɿ01Yݘsnhf"-ducέÙ'Ս9>g* Տ5تg*]u۱y83UL]};wNDj65ܷs'DJnծhtsΝ*vM7;r?o_[;9=To',[r'"Tt}wm 8@DjVn6"QKu={n3KXvRwq6usJ?ݯ Vwsgaf3KS}tFGR=8Zbzda,f3KduFGRԙomM0@Dj+sןZ=2w6fJLFGىH-ܪ5=2wNDj6[rzd욁RɭZ##sDJ ZE֟#ϯ]_SܞGps]Z*Uk{dRm5[> ؉H-vV7g*}`umÙJ}uk-y8T\SV7 Rc67׉H-ܪ{m,7NDjvtmoc%"RKwѽ6WܧrDaў>;W3KWf5ؚzmqR=?Xݧrpf^Vin}*v0gٞ>;W#Tr7ܹ:['OՉH-f{Zn[+Z*ugK9a}UnA\C77܂:h$tsG=vw/>֭T镩FB7wc^6 YQrpf"^6 YQrpf2^6 X{L3Sw\5ӉHMF#;J1Tm6wcz;t6㙩+3 QrDnS-#7NDjwF֭T镩NA7DzM8;Y2rpf"빶Rny83U]Ne&HMF[Fn"Tmt e&҉HMܪSmk"RSe'Tt?ZϤzNMC54gVb?Gn#p7w{:[5ӉH-fYn['Z*U;M=HRɭ irDJnAVK'"TMb:M=a,_AVK'"T9Īխ$7>glm{"RK^sovR镩7\:[u҉H-܎q"uDDjV-n{t"RKᆪխ$7>gJLWщH-N죃,֭R-n{t"RK^ZX+rpfܶ^G "Tr7=[WщH-ܪEͽ"wNDj6[rzER)WV|*v/M=r{>Eџͽ"wF$jV-n{t"RK%jpsݣZ*ܶ^G "Tr7=:[WщH-fXn[3!Z6T-{y4Tze NDj+s U{E},_ b{DJnfC'"TdV=kC3׃I?6fJL%s9<߉H-*[i;'NDjvdmO)'"RK#Y=>gJL%s9<߉H-*[i;'NDj6rvL䁈R5Xs"pfTvN䝈Rmf嶥[ek9mDވD-*[i;'NDjVnN9w"RKd;yg#y\C&=?ݜsFDn#7gNDjVin[9*K7ߜ;Hts*UڅۖcFDn# 6F$j6*ݜ`sDjF%o}L^ʫplLTmU9ۉHMF^lNTm'ؔrHts9u'25UvnΠ9v"RSe8 sj'"5Udy[)7Ù+SnΠ96"QSe8 sj'"5UvnΠ9v"RS%Jp2h̩Tm$N9ډHMF⤛3hΩT9U*{%niW,Gn#mi1"RK%JepsNYZ*U*sZrRɭRܜrDn3--,H-*9-gNDjV nNZ9u"RKuݝ.g*[[NY.Ù+3SܜrkDJn朖\'"TrT7紜:ۑ=,H-*9-gNDj;\Ny9 y8Tze*9-gNDj6SrrZrRɭRܜrDJn朖\'"Ttlm9-f@DjV ni95"QK%JepsNYZ*(<hJ;T_n S@ "Trns DJnu7|NRmmc DJnu7|NHRɭs)Z*}79t"RK>?>DDjV9|ЉH->o:[p S@'"Ttrn[p S@'"Trns Dn>_n S@ "Trns hDJnu7|NRƩ;}[Mxq;8;4TɭNmiq;[pNx"RSeqvͧi>q8;4T[ʬ<*>qybVϷ|v"RKEy-|g` "Tr n>؈D-4Ϸ|v"RK%:-R8|Kg`""Tr n>؉H-4Ϸ|v"RK%:-Rmfm;H-4Ϸ|v"RKΗo)|* #ǿ?U_ ʓpONDj6ϗ嶝8T DJnu'N>:[/pONDjv/~S)Z*78TډL-|O|*u"RK%:_'JRm/m;qH-|O|*5"QK%ʓpGLIKT٭+*w}:[}W'{*}@DjVpI^jDn]7NDjvOߟ>uͯn/Hu10wnzw'"RK%zDJn΁Kw7[69m{/[ "Trw^NDj/WPJendstream endobj 205 0 obj << /Filter /FlateDecode /Length 2406 >> stream xڍYY6~_aX#Rwr$4>l˖wm˱$>u[N,bl3KLVťg/OIeZIئI#+e?'өr]lY>}3c:l4ˢ %l'⹉|a͢o9iGh{?`skׇmqdĿ+d ?yUլf!%ma,~ [Fa4in+8 ~#Q.^pW\ 68/!P0҄ǜ N wK2 @;&QCN5p@7UDh&d@#i$L_Q6$'kI[2d}osLIp_WOsb2< ߞeU ׽v"s:%F͐jס/Pj U 8i^4պaETm xQ9 Rҁah+ェBmDhÐp^,ѱ#9}|d"QD_@6e5 >TYSq  EcÊ" s2:Xpf!)=!&9#ΣȾdQ Fv `B-%\:9#ӄNNM dO2ĢR- 6R0QxFxX,L EuW`cå8024 /pj79T@3E1H1[XT& j,+$o2.ړx=ænH1 F%dTzy;5Ss6fBZ,&o]'E'*'!6-h54Xgqqkk;9臅&v)ڱy~o#7k+. (%6WQuӂd8WVПVFK\@Lyv#u&98p Ɣ Np$kP@ Dt#r/͎ isr>{D:qJ^A'K7Q j8b5ॹ !W8CxM\Uw23NjPQW#jJۆki4 1Y9_)[ ߿ b?¨"T;_ܬn}&cwtxPgkp0Fvq%1 R@_:R J* w\6`sYsGriB_DG`+iMtݨőfbYX߽s- SG&XKbJ!zC%fl4'-1N\a*+,ٜ6HaNAL O|8c\j,_R%pRٿvm MPQe )Tw#׾j2h=m,HYsURͩ<65qq̣> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 207 0 obj << /Filter /FlateDecode /Length 3137 >> stream xr]_ɴ3B,mҩrqN^N@"UCb|uwAB=mg s8{oW,gUXI>ƄE^nWf:5YpoyR{Xuk~ u9qp=y'DwUSQcA0a h7DD9@nf:*[Dfͳ<͋uf(/s("- ~_ kOr5qhs p!X ^+k(ImuG懾5+^+~y1,tN a`~p pFbwh4FYapHim@` @=0 /6D`Wd$HW oE5FfǔxG w"0qX\r` DUAМY$;a`n*ax^8yǠ=9V\P VP@ z'[J; k!K4<#ơ>s984 S78(LJHF',Ml)whN79yA-egusy)5÷T/`pAKC52TMʧe0Ucks ܂]yXi\nem(;Xyt6xu"?|yVֱ;PvC|8UB0'x&%PAQ5ު@5<| zQ-,$=N.+(dw+ÕYa3_6.()+ =l%5, 2qN tw׊%Wff1;+V-j߈ aӿ0݉DHD k$د !qNuN~mTDfs\KOb =;? BE F }"|_ڣ,s?Xld$#Uɝq!swq6!SA5Oxy`@9P$z2 DI[VT$"-)Ήt*vT噔'ʳI?ӏ;6ۿ0a$d9<3 :-%9G95]H26.H]fF5s%>z_/YBxkYBX giXg !e@ڥ[-nOpM(eOD)*fڳA#`kLRLژ$L2jJ2,Ғw4kSnR؜A޷rjKIֶ&[$\z, @ tX W[~ixdk<h* ;CC16Pq?hsrwx͒,/~ n& r %vB`WG1;H._7CЊ cz-)MدS :5[eO|4('PEwM[&gKӒiVb*dbzG&KI%'r4KlԈu*Ic^41+K*4O!yᑝ+bpy=!bi < r[ZLaZX,8Fdz3Y{)4!v]px1qA놧b֒ܠ_Ong" ,2x0cEє< %,aUH@`osOW(ha5Rea²zc4[K-F~;W_mUYA 'z*+]~;WF3\i{UB_s%<Wa٦ "Ұd\+L[DQEޗtŪ2NKS0yB=c3g,!i3SJ*&&W.'A0Siʹ*1 h8d`:-U|֓T5 Lm k̑kIX(G E =,$4Sg\m܍#OÓZ}½h9 \Yv8Wӧ,RO.3G)v$AKGze*atnii=Љ{ޠ-.oDo6 D(`@ڎhh O{CW^}œ;Q. [݃ߎ_V(!i%]NVNendstream endobj 208 0 obj << /BBox [ 0 0 432 432 ] /FormType 1 /PTEX.FileName (./hexagon_binning-marray1.pdf) /PTEX.InfoDict 42 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 45 0 R >> /ExtGState << >> /Font << /F1 43 0 R /F2 44 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 66176 /Filter /FlateDecode >> stream xMmIr+! |, 3ȀecC[+TՀ۷vsΝb}ן|_o_??U~R?__ʏ5žb/|/(?G?V}_/~Y?7/|֏b7ޟ7[o6m__տ|_#O?_i_1\J~s/?s?V<}?5,O%~ML0_cw9돿^돿{ǯ≯{'^՟p\366]m?sqֽGq,ʼoN~ԏţX%. x0[?cW?]mߌ?:v߿ӯۿǯ_?l~FuW?%[W?_ufcNVv}QK| t+];nq ƭoYΚp>}/o#.]v6\75|>nvq֏}m_~5ߛrsb0߯^h+V|![{۫[o;xvﻁ>2c5Gv[BMm.[@~NsKc?"nE޶~}ǽ)8(=Zż7~brj<ϭO[M.Mm0V Kn5y{c#eUe ur-N*3?$'h}bt4/w%脹w>kImtĘ2Ɛ]~Dk/?vy}e,`CW1o~:x=H*=rקbv[拮9h˪\^oTDM}Fmw yteu@.j"oj Tp†Uơb+PtQ5:(eUEzWMxc6, | &6LtD{PIy0pͻ/|y84z_Wp{[݈-6j'TUϣ,C|ڢrx-ѢwaM?hQv8[6:Э5e'9|#vktG/-+ӎ7~pyC}nK[G[TY(gl;`mdXUP2Azd{=uA*V=8<ݽ}@]\:kGUsތg?GS|_E}/kjwkmsR/ϰ]_%JW%^|5 B "$UN9Ow_kwdݛJ١b%W2nQkׅtpznKQ0n)]YE\'yn_| 0N'}-tnjQQQN>} 'BÈ1L`5c'')MT9JP A.aoU:NoCokx=#rB6]ѢQС`۲$~/~E5|{<[6mhlܹ C<*,w\&b<.v>#~pQ[ .x rVּ#WvF w94Mο:١Q H)2QAcCkrD1cvznuD?×oDrpl>FBoyڣ'UB=m0*TU8su?b!6MLQA֖Ck7}xa;S`W7w1 !b VccK{EVǒlniD8 b|ʯIp?4^}biu @}ef3%TV5]ʪ{Ƨ/Ƈc+[ ]c1*m25aUao.}wkzㆷR9Eh *_a5>pZ @kP5>g(!$JJH⻗ܕk~m-t[[Q!C( +~百`jlѫ~;TBbm̾סy@z7C$4[W "Ƀ}CVHQ00;@M; +HsoU#a'b%\/mP/T-kzUBjZ%NAwn%c,&}8&L^+vy0 1烫}n᫨JXJ94wQi9Y1sJvٴL]D5E.ݶ^1Sw!`vb.uK]cC={K2)Gjʚ} $YѥJ'vVr[P\㑓FR۞`$|m1ydRuo)wl'qXwVNd4"Pҿ>OL>^."@ݖ]m iR3.0$OOFqs_f{ =gKA۔ \B0̯b=9.6֜Iz fiD.% &>1b@ŠZvm}*v&(8Gm=@~j _|Rkɧ&AbtsUs+Hl_7`D @o󁊂i.QZ'zƶ zMAa:ӑ0-QO!{y wWiUh xn'{ljn">%kl4+jٔ}:SyjUW/ (ڼ0|[;@&sV2!7lIvz2 랆) |e7oyt _8FMĚuĉ6ϸ\$m*eKr܃xR+Z+Z3#|Q ]rj^ay\z-@ UE^uKg]C; ڦz{,;Gk1}1 M:vA&ͯIzU۝$d9Η#Gn]MiH(%n-T ViB˒ջLF 8qFI-.ᣌVO;Z] *Η&BN) 4\R=:pOd%~>v*gЯMJ-Ԍ-KaZܦjJ53&Rv7A>e(dfC}iQ6t9hX\>S+ "m8dX.E^u`.Ԅy&\EPPnr\uw,6iN|Ԯ9ml-2u/O 2dt0F>K3]j*)QUV^M÷=e"9Ѓ3ߥYP.|V詏7drj_L"Vod6d`lP*>l8.6*Ҥ8'(X8=ćEc F,fM,6 .q>VLB;˖x|ٺv 8LGaeϽKY9y[p焩GMMgu۳rbAGAԣ,dUюQvi_|'[Rs0y >VDYlLsvQ`lo7lb|싋QhSp+Ú` C߁ӷh>aB[ZX l3Сz\y,a!T5kþ<6t 9-OK~Z$`ۅಡlY G !_>s;/y9 ^VDjQƀ|1Q04dkn*ˬ򀜌T5ҠMJ&Mܞʊe7KaVDtPyc7|hБF`t˛ ԣr\T$g19{;C^(֡Mzu!Us<-dmGČ.;70؆ofT&f>xcm$< n!qE,XHߠ. ], ҥ@iHapk0:kUv Q$Cq[^"p:NLBqZ55<=wAx,YA}6:BG{W6|_?JS$-ɂM/(+ExQ[dv*т:L_bC[!~ Ylһ*c;_ Ơ=+zCS>BާX`}ʃcáE91%Fbq~Gbh4BiƒنV+Ƙ6LC'\ܺ as_Z1+[չ#vƂ}{tDc3R߲h\NйZ&sOߥ,>H@- 2Ǫ5ƌ*cܮ1Xۛ2u9j v^QHОEq::ZɩfsMۿþoP89ꛝMr@v;^IgLXUG,Cg+5Cdx`CAv)YJ'܀ o)Ba['N#KKnOe9ÄĮ' w0@UyMM9qHKM!r\6[wJJ{e~;4E_>$=$[yȷ0Pg}5[e/VCp2^դ5qL'l-U؀o[ϓ]>"T[<-,_Cg2@gխpVQU/dV_w:gG +sG lǗrF|e(*(Q)n}VY+ea'#:s/bF}Pl 7Ele*ar{/=h2S%p4]&4<2)c0C,[uQ'25hѪv.fŒ-b$Ļcdz<vCN`Uͺ"l.l$ 5*nS 4B- Msaf(C3ف%9Zݬ(t?~ c2);|0Ô@R>]3AVS~Pn}+tVܘث.#N [!v :7LH4[g0EX7F/&Ao5F/E8N XÒbUp!evmle=l,{H̳ ctDNXwuRմH`$ژh) "armV֏rcC#{wm<2۳H3O:܄у΅#!je8GD1l8>U4.u) q=Ls@T=񲃊)';M= MI?K‹d²a`KڢH" ݆9b=* :!d/D3L;E$X͹W!?X*c{5[,Im${;"@G!=V1-&ClEDYm[|\3[h)Kē!E?Vi` c mhVPꇯ*o9R 0PnT+b R)Uz8"6'}<8M' (rhݚMDa3jvmr?̖{ 8S<ͶJ gV1+a0 6y&Pwvc?| R"Y(6aƴ(KF[ c'2i>Ѿ63J%mZ-,g5مTRXdw:}qwR4Ztj-+YS|g[4wW~yȆkJx3o(X8zMb-0Lj`Ch1OnGQaVƺbxTjV9yHS& /i*!x:5q'ctV:U- Fhrjp]1 0,mﲦ 5C0MP9UtVbܟcDlVPt1Yw.E0%_c=La)J<\@ @sOIV 2fZtB{HYپ"փg=zb*܅;dEʬF w&z4*\*CO%f"6Yx5b󭼼wDs9"CX{t PܙP3ӦEwt> 2kV:,]6|ӪX E3kwҹ&mX,wv>XWȍ2}V6h.jy lK9Q୪<BD ș&sA5\<1JXv&z e rTUϏYHrAA<`'f;1;Gbȴ,uv(kc6't'3ؘq4Q{U3Jz(RWXh[ab@"0l#< yYVV82:yߘ$r(]YU=\h4Jf-H4u(0ru44YEI UT<-7*- ~E=sԤ%e$BKљEq3[ob?e$d@!gGGÁt/ZƋtFWM;oKCńoUN~+L<3 '#HR>g{ۮٜs%UCu 3[ʨmbO> 3bir3!Ȏ;^.iDaVҐ:9'}J}?|293_Xڑac<{@$k| PZWHW's߂xshC=tEEbT VӴ4CvIW`I8?K^OOCQ+z8WƘUĊ7 u+v/ԃ5w䨬0$H2wbb>A2z &ϩ͊uy2o\f, ;{okC%\i ›UZnE$W(FD24~5m Ҥ)uUCmOёY"1mͽ %l2(wpW)m`@Mf5 ӐUzpE&#yS &ż6EFy`w b{"^>Ywfs36ᢍP2*g@CDK7?Ef^ c _ۋ`AGd? Aab4Vy)L]jÐJުgF!c ;`z{kÌ6x%%ifLeiv Sfp<@Ӭ" xa5ªf+d-Ͻ~c؋os i*6MX1"ګVXnV\qLCp4q|ʀ cGLqS(YFM:G(cu Q >%TS>-_F1"GFܞGIHngS !ezI N# >XRxRG4XE sEkkF"Q{eXQh3>=P7DuY0w#ѳ!h^>vY4*.j`mMm酃DԱPTQ,H}(`8qSȢCfVaX= /h*c K$hG>NCְ`E{Z&Ei̐M`F 4X`iVyc6[g Z]SĶԌߎjכds'<S~y# 8qp{KÂAe#rZM+2@ l̠ @ )%m?lfi\FP~9AƑ*wap*E vq dmPvU$!agr5LPmB/ UCTp } ]z@Y:xGyx%%n',q8"#]qEi\3in߶7bg93xE݄\0l͈B3θ~IAXNmq+\#,cDZL ʌI2pax!Ix4X.)'7JBۖ\tnj fU!uB=[RPaSH1|He4s{ QbK僈>3$uː2=[ >xpPQD^Cs̙H'- z'V6aS&ͳlV1:d4I nD•O{oP_/@}PA=eMp]0вrDQ*0袄Z>*8'd5K4# u; lo@g[DHzyzu[eȁ:yQM.ty "S~|\3aųNW1`Iì:t6+K:5Gv"y2ĈH ! ¶ETi,^f;;Lg߮9!PQ 4$[ܒba^2Lgy O o2ܦ rP|?{d{u.hW*!"_#U!\%f$"U!'a$lso` CPX$8v/2 fGZ3vlnCV:kp{<3$ roϭP%/i{'ڟ"2ؔؤ_qvrCo;&ܷt}U4O|ȅ>Gxgʀ\UݣaYQ-b^yh ʺ7.6E;y ,15Gn P&DȚqAڔ⮳|z_OLvOH=.!V:5t⻊ pRI-LƖ|JӁW65U7qa+N5څ1Z1Mo*蠽iQG(fntc*ÙFMY 3ƜIDɈCTL[p)&\JPxTa8ePGX77f]0g $ol\t4u Os;ܽQ!lI]XN՚v5NE UC Ŷ€UF;=78d\YMT|YJ2hb?yr+JkV^ñ{ͼ K&m x1⃽1|[bU#RmxVyB;e yJf-2QRP|&;xRwD\ 1%!ubeoa|Z3q|Ox衽ĻPeyPGBf*:YD?I\U&Yͧv[3{ ׇ w[蹣ӭ/8Bm@Q(Z/$EY'0{&*;rvH]/,gG" g*Ml >b.dC.jdG5B1ZrҶ@ MشBqfZ=*2777CL(0FcV2&{G{ppmœ2v`1*H#2TӔ4%nL:L٤|h{9 `ݺ UZ nXBz& 5׋'ӯ- S6 yDc$i2S >I Q~X<#qa:҇Mw?w+*!bT9o΂ sٴ!_ω׀z[Nuo+UuaW1Q` lq8f}rV?v4^0N=Q#$]LpF\̰v9hBiH1;Vd (a)U>rm[v>r(y=̪Ž+o;_y2fָ=Xgl}t$+Fu;#5.z,y~HAڈVh:b_C4QK|_ci45( ,٠^(ʖM}FD, ڌ8Fz1@~o<}̜ˎNBû-.ը|g#{f ]ZTs~87j #fdsM|! hʉH ښbo)ͷ9A< '*Ƹ(Mw[Eet !^!Ɉ˂5MEa}ꌢi22FSͮ* "e]D/ţdRO *LJ>l e֤!l 0 t^ޓSzb}P}~iԖEcO-ER5-f3SL8QHpSԌjnp´YH=9PѤBo7FC~Q?9N/|:mD,~;`R) #J6\^pYWdlg,%A7\H.^xp 4Y1Bͺ\C!5gtm#U 'ڂ}ʦvT6+5DGx#G PIֻ7;zAuʉ}ړ26}arVM 1Q`ζe:F}OQ8/AVd;,*$ެ9q!jy{+tq;*iiMӯ246R)݅uo޸%i>_>mƱvtكI,0@Kjâ̖MfOwFXqG}!6>M`fOk`a:"sNQтHgf- K9WfuΏ.2:[UIQwʙ):sS"QGCo\R>|y@ 2[F_)ZG&*YtA]׍#&T(A=UVK5-dbv V5_6]ƭEȲ[vʪʑ3^EoL+JU4jÝ 4Θh$eؑric>L8Y6zmf*[G=_A,BDHۇ6j6v{4Ì Ēﲠ/;N|EAyGu!̊M nz<3(v-*c9eFP7d*)jCi~ݡR'OT'rBGNfhEoC\Yt;m/ [+ڔ{SڨuEAk֙9.#^ɿRFо` :w`); !S#4=LD*?di] WҚ?m˷888Fg*@Fetِ"ЩBx^'H &FY7ZEߝQl0̦:ӖٓVW(%Vj<M8Ժ %]Ge.~S}%;*)`6tgYPC¾<@_Uu=G烑[=:rk@'S \"J^wͪvᜰ|{C ͅڦC7jt}vɽmɠWfPH{4ń vʴfq\ueCceeeMEif:j&6d0!5n?(Hse9g4a}Hım tH `b4ͳӞz6Z24MSP](` ' O'gCD{G;`vJW& 1hBKM8Wp=$QSPfVYˊBh,Pju Qe1@F dF2mrQL1P3^G|Lڧ;r1EК[|2dÙL!9YxuF>DTeC;ߠ0WaT:E)b̠b~rYYx ~Di/ߑ8@Qjr¦-S!=ҰbE?#iy*ϫH t|DYk~z/Q6MU*-{M3Oŧ3*qJaƧiMnau4 *⋔Vat!6HQ,'H!ЦȮYށIH}ʳ;XlLXulcЋCxJFc'޸.Rg'P2X"ު0[qXx/zy*̧"@.|.J a]t.0CHEQH4HM&MF!p ԙLt?s^gNCE]30S.%԰+lXh@-Ȋ]qܑ+lĖ lO\}=:- B *CN<E492F ܗav*SH%i!'6T`|?"Vn+#ԧ-=ÀΪDZ¬1'.Mn5663e 3NW:_4Rb1& @}+].fp㹡%߄tya^oɓNfu!UƒlƠU/Ba,:,Hه+>]69 L }>BflCLe{ni&_ lGTQBͭ]&̹m[]֔h|Y2*7%CĘ;A-D5H8ܬli_U9RLCsFʶY<;YfB w8YapBfȤ) =g갡pYw5v*pfbCK$X5@хBL)TjD98Y8o\i<@ 4*Hr1 6ēl<,#&e0QGfCEc˦IP`,9Țb̊>?W$ US# ` pă 'q]fHP7?ۛSU>hQ^;$5 L8Ef並 2{ot0*3SVGmJ.ʑf$^QȜaң!`~}>^}-o m۷FBv r; 5f`|e2xWl> ,C6gBijq}԰%TdZ<5()*I+|p,1=nG[Yli;^a%ʆl)S͔5* $%Ca>5Af%Ͻ O{FHk2ʟ~{x$f6@ں aOXѣ2d.|!6'ˈw|32=|XnCt@"'dcMsʧLa[N8 yUH0oN8~*N ĹN8H΋:G89D{LXث֣<٪*:d,*24˚S'{asea[_YૐTWӑcv:>WrD& M|63o8g 2 #ا3˴,X<o!ZB]xd]a!LJ1󆜴 )&YIUn8unJ=i IwTMz2:$ LdmTG%խkRO6HG;MpM$xڣ"cH@(卡< z̟jňfBe=&3 шA* ;O^6},* 򅍍?҂DV 6 $@E9LZ&38E]B4+KΉ/Ѭ5 ;l|^ m6~YHC5)~p׀E $/ߔCLǰ '4YV]e̫4OF$H? !G1Q H ̇Q2iJ7p (l\Et 8髫}.0A6rWb" ±4'Dxo6}!6$Fw~{U[:o]{y~(F:UN8u,ppƍ2LK*za+NN鰀LY7m%XU8WQIIqȻhV : =>bͱY@iM`MpƷsiiG N+Tږ<;Y%%yl~;)kv3򯧿 I?tҐ6aKY{К0bdCҶp6OﬞBv=0+&L l1T<6tYcu"Ltrz#ƷH(btUt TQ߾ ]|yh51o-Y=@<*)=^BJO:e q+#Ow!7yj2 H%s<%CӞt1ydYJuV픇00\/S0V %]>_bĦVRYe"a%ɲGB(2lH.emS ,`P5,hxi]K>t R'mͯؐH8C- M -)I; )48-7۳.{ӡs& o7]4[h"F" F7a2Mdmbg#Q&X>MaEz^oߪCCOBԴPAs kGƾ! a٬dFAym)بncJJ;-}a{Au6Mg"3B1^DE+=\7n]T6WA_;hH]òc+SCRCɅ2_ze >|tba'5#ї B9W7lUWtZ#;{ĪCj:r(!%o*ae\!0o Vp&8(&PEUL 3g"PjQr4Rrp7:yl+N}V\-@ETM_ΘE4j]POSGN8W\۷t"0"sv\M" *g3|% ELYeS t6ut?|pνdz ț;scb<!Ӟ S 7Emc1ҭ=aJ;ڰnp"R!w QQ;&|G=it3tyh Hմ6YmH*lƜ-N޸DQКo[m\rK4ŚE}ا8ȣ;m~),nR5؀A"&(57f_\ 42T!Z7Û1- =*PzO}=kND"qmj;&Е1;&=%اdE;Ӈ ]^1GQ(Da3[]L1Eܡ4uRE,M|Ͻd~,4Nkc-cҠq0؅%L4d&a4`aVUѾ0_80m~eɀ-h7tBQ#E>Y9RV4{NúŸ6=IroQp,23u1zYOvptGZT2'J ԆVD_)&q<_0F RY4VN)Ӷ"S_~g’\ʪFX5۷FY9u9yEz,MY.Zwra>}%sB 2MDc5 uʂ-B^! Cˇprl}UO .&j"' ñU@ڪLEO՗Ay2& 'l[+x4C ώfUǒ1d e"wdS +X, ieI 's[2?c6)t 2$}y6 sH!X6swdL$4xl1dž;`Ȫ[-كp-'QtGNj2o#,rSM* 5iMS&R^W @Z\6#$?#MpҞ6yM Zp?h7Ac_5X^}cyPH)'.|.s2pѺm끺 L76\+ g,h_/æ:tJ#I ^d˹^ jcTmF(n/BlUjFE3 ɛGl\ Z[$ . ;b}\9"ݷ$`vݵBt:(+-xHX(Dк%2tZvg^!7ӫN\rI0h=۟HH+5{_a(HkO' 3A^e>VvQ3 .GIc 7B;a%&zQe0g63k0 3mo)8~$XoGoSXs[ Tn^. x; U9=(y閎m|^BXZ~BUwftWbXɆmQS3h#n R1GbIU_~uO_"|i6HV[8)l`faGk0*LK"%hag0#u0R4>jưqOi=QtJ@jZ:`' )`+t*m ']vo@TD@_7Nˆ~S#Sc'uġ;ߗܣ lFH>\?ǀpV+˶,r)r{Px](ֱC ߌ6hx B5X(d S#ēiә);]IjB6dzWZKZtS~Hы U"*dAв&Bs<@mC~<N7⠦mPtJPHH_Ի&:D8bO6?jo=,}AyoeX!4HVKBB*txSI7s?{׳%sì0Ӎͷir `1&5:.`S-}Sߐ*jkVFZXir8a7k-8/ m+Ilq,MbLY A˻%^j߫`C, iv6dPt>4KCȨ1 9vl2+44kCv4ɴlB%g}Bqe_ :lJMZ$Ž/u-2tmVpTmHM)2跻!*z3&[iBaZiiw 'J:dVkL4Cm\:7f6!:>eΆ&3B[ƭU5ĒߐA7 e>a|Ř|L>( R[l0c9 έIMimTߞNh8PrD2 m1[.FZ?2l7Si=`g *'׆f_U(u챐+n}ºi0Ufct1.,LBuh׃pc':IGﲠ^pd"1Cy70Ag0 :PׄML@)*[︍c4pgX-4NGIcDYtDOcz|_>nLyX8("ـU崗t> -VP|`YNQFSc_oZzлM2YT65sw(7!41<]+-)% &_^)Zc+k }ʷX.\vQ ^~õgdǃ'Zv޼u:Ytzƞh.AÌ{>ʨkoMYvFbA:y/dz7բe^ #})% .Nx(rhxFC 4 `M"iG[jL?EFM1^XQe3{@]ShPbSBQ>6jƘlV&ehw%贗N8mU_&xn1A-%o](zYyE.˜rJQ>XD@N4SFIs3]EE+{Xm U 3!<۞ 'La:2Tm7h]|ӑ@6'-IY4 1JDtUM"J}GA5c1GOx) 2՞9Z= %,] ᠝K%R%yӨUa$̴k642)kX噏9`gv{I(hsbuM5; =$H)KoQ}==աjoB; I'XFIu e F=ސ gB:#谳b%]OhU$Mc?wA>fהڙc@y'!DuYX{f>b֖ڿu5Y; e5 `d9p<[4@hI>Q@LnR$i0wOlg66}9> c qRCe3LZAJweq2(O)Q4{(̐Ӈwt+i{ )<\hoYhZvN^P_ѸbUIa chNp ]\_AOM@{ 1c+xC4b:@]>>u4SY o#_C!IX20JSw4,k Id{j͡)A5B57.=;{SiH8N 礒0X7f$5䤲^4Mz*,j)tL.4\u}=6jªV?2aER@w Vm:PC/D+x*- ozB䏴$"-%aHz@G^dR qqR75t>Sº:lR$ݰ)S>3Z1+eE!zno1uY@۵jx 3X-["H2vTZZd A**q.-j;$f$ vcA1 eAk;"L%5ld 2 _F),f~Sȣȿ'-c(s @:#B>t8Ƒ庺;kLʹper20W7wp!]8\WdfM0h3EAm:;DڐגC\ !MXX׌,OmAbo@Eځh(JY ]gw<"CsBDaD'b\}]2yY$G&IF :BeNU߮HEC!,מUuknYY[ނoy3SV 3n{hffWI܁ 2ŵf(^(<T;4хf"V2řMTH΃${SYb5A <18 XpkKٔ4&̊[ V ڇBFXӲ[4]0-Lod)'sBáӃs(O*Lj?%,υMR"^j%,C#/*og-F._9;u4Gc6V Hn3a2VLB˞"-f,p+% .ȊY‚^&2sqG}6/#E1pKDZudq&e+/`vۓd *LFB8жm=789 (\Y['n皈6.eOZ4o6U '|:n6 _BB'PsB DnX;w%+êב*Ou8q8ccK6ة͑z7#]ļݵHoAwŽ},NJ0NcC{ /nԡj}u& faeɖ0=S`4Yϳ=Ě~NN[R[b9VO^6nX#!ͥ! #33V]34Wg W#=agUXUV\8|CgQeZÊ<}RpB@-ZQ7%{8Pu;Cn#tDgd06uEbda4/ ѲOaG8o&P70eUҙ2EA ~6Rj0o5:7**ԗfG ZGm~<ܪ"kg*oLxPZt,Hj0"<fڸ)?7X-,I SS@ũDUu) Npt ӴsMQ K;|]wyM0 YsNч#&b;'JߧUW-PՀ^ɑh#WP,鴺;wW ƹpK.`l% %7/VY,hX1didExd1{MOœrL.XeHnzoS$4G!:8Gz?{)U*}ϵ&B km#\#݁ʴ"Í '~#WM:>r[&DAIToy0V -Ž9ZJxe.!վtJ\TUv:¤Cb$4!4C9e@zqlѹesʢ_#U;3_̦A }#?Z}ɪ=nmsrSTT!}5Y.4I=FD:ƀ2"/h=.L% M'uGxFo!_ڔ'ʹuY`b.V̂¼ It8:ozb.doU_}4-̢3:\*r' nj3o$OM7 +N)k[?|FLˇPUt4oOTnu5C9cOJXUGwtS Dա2.$_w5UwwRp Gؔj\+0IC 6%gԅUA6aˏPv_d=hcJbȺ",.PeR o8M믺`l !dq:"Q/3b̑B|p}p{|t? gq^{0޺%ԃP [Դc\|Siah`7P[ /l 5?Ǘ'qdqIQ'Rɔ'$xM)ƚa/ gԅqn]0,4f $ Js:2hB2I<ʃ!@$n/Zf7?s+Z6z&K'xl};dvS]W@w@]tWQ 3ո/厁yiuLf$Ҫ7=nP_ge/KrgZ*F&4.%~:*-tO3z|j¶ brpq_LyBЁ_ .Wϣ3bV}k\[fO~TeO2ni!cU9ƐuIy-5!ngQ`0@h֝;L^F*% 'qG`!w|!ٶi'>)A. פJ62S|{8&OQ+>؜̈6"DZe2+v wUU?:6- m639 d^LsS7?H(qH~huopU"%H4qGEdM¶7(32m'랬+Lx9dflo; VL"4kH*|[SF75L;-?k7s+CJ]c`\AC k~}GR3|}of f^:efa1#3 Dw;mm!cb,\ۤ/j|m%VyX[4r\6x0ҍϷI3XGrx2Am2%-3PRpc)F9T0-Da{MW'SWR g_[Md²۝O7,)LMp |~{kSo$M Oŧ#g=Q[{~ ur:^߰<=!2mALs{IEv>M(UE@Mb_ui#"rjC<i +.ډYzryGYs𔉊*(Pl1eEh[Ճ3tDtuϡٶu. t**;'uդj`(Le)EP]p`#(h?oCꂐ_ ' #OjEPs u! m$!n2ڐS^Id͔/ۓf4X|HO)Kc~O:`ckB:9o/hܖ*vlta##Xh¦ZF[\Tu0AYxw7=<"McHh7( |ZL'4wNx-eOF$Bl+wّ&Y5$eHGth@p@QH Q0[Y٧_`F_QnuQ>3n~T.^7ڐ ˂? Ч 3:(g^dp< /^is\i>" f^7,2Ta^4 Ez9 >m/-Nج .s_C%:i;$db֐iҺHbe1m?7X4ZRؘ[/p_aaVhĜ:V|f@4%Yu²6j WR苃{^aTvd"qDc#2[Mp/ZѹB ȯfibgTwu99㝌:-3)U܇齤`}FC0޵,cݸj1x#rJf$3Y!qk,M?Q6u@Ǒ&afuYH{qeBUusGsb'wtFmnɐym>-\8&;R3ab:a}kPߛ\f ÿy[0P 0 ^X&0J@e A 1Pd;_NBfmIgQY2LzJ!䥾2Kb.Nd8}BkE »[8(,I^d=\t3R\|#߬&s$jh,nQcHy WfSx1eQcFq׾,š\`[F v6-HPcw`vE˔ tnY0 ʼ f1JG3@b'A~pE,V-[bu]5a9tSQZ@8d1ĠZ1 BYIQ"* %/)uG1]VYG#'*rH@pFpeYaL-o{yh.w&A 7`m)y0P<-7t7J'#VԎ2Em [-A aPW[m9R-葠I XvqyGyR4AWFLՍ&N$PYd^4؅ li`_]RԵȽ84[W{2eWQ>.WuŤk蠉I2[qr82T[zCS*_=]%4ΒAQ/͛;E(G ]1Nnr@dFݼ\q@Q+ƨ!@w>,VBST~\.\'cI =Q8Vw/+p3X`BżdtE".9uCR)ҩ컹ᳯҭ3T-R㶚IiuQ C({8ە}/fмzP:ECuԧ_PYkL;~Re @y-.餉7mݨ!Qv9zGOܵ ÌlB. 8Y{g Ҳ}8` 6rLZ0\h{MC~LmH|esjJ$!ZK:>n aHoLY2 RY?ךGw6 1B8g[H$)LW x]a$}=:AvM'kCǛlHws/l8Ud j+otyKc=ɣ&ЪƎ,51 w}wVY@ٗb2K6 TXnU*)dAToX$? #Ҋ1sR^l0,~\zA&+jM ŧ95ܧ<6DA:ALm8?ݎĝ5>Y0cVE=r8Ug{;i Qu 5VBĬ ݭ#0Ru5viҖkvխLr%R f|<;3_L(ܞ?%{q} (5]-a2CB8WF|Ҷz)zO6¸'UU>? wz] /eQ|^bn :]X A5@u6~E^yIO娇WwakvL0ɱo ,Ҋ[4G_E}ˡN>\@~D.'_y<%&hR6]hNؾaAaCܕtP6gtPڨg"+[]eG;',h&A *#t: da8vp mU0Q{8i} $Wn2 z\UdDS0C[n%R#dk0z!Ub*V^g auAk8vv`;n$z Skʅcƛ;Gצ} ̬RaZ^&0qmFƜچK^N9-sf<]b"̤_6l>:GFYx*'$4Yc z_r08e9lbY$`(x^bLmpH132uRAi[2`WQ󡨥EjV3zTAQ[iBOiR|H81g%>^: {a܄vz$K(WV# 2Ƨ pX~н[#i}uƑR_^ eq/4L{!ޙ#x 2(!85F(i$WDe}{ol(G$4Fj(0icZE@%G {*YxMThdh`"v9C.d5] \тWWGe-ʒ #n|,c('P\|\PHk)0r.C؄.S!3YB&/ɳ3* @M^3"w £C9肆ӫ60_h{5>a$Nzqw2(s@'!Ld`ȃs蕝 geRYW=Vr|LrQה++lGLr!6 7hڦԏQ  [PƑJM(,R~N}Nñ&h7P=)]ST\u#bXRӈe!5շCœĆ<.k4tzaJ^VLVk&ܺ:B G-(60%tq5IX^CejwT`Q*$Cu2j祺zf} 7F,L)PǹOeȜopFzTJA[iR3_㌹MZ8py@ٯ";,}( ިQf/MI'(c%B]@jmH< viUVEf+U op$V tœ bˢΝaE(x̯ZΙ%L^!iJLq&ekYRа˅5 ztΠp~Yd\^[x.ϰFfg4p2`Kk-!{KS]31K{M4ѽt,"X\8ڈ:Fģi 5hX MA;כVE FyKaDNKh0UΫwk QjftL򡚔(ҙ}iB {G nֵB1I|mE 2(,nZ%}wх1MT`gActP0/|.(cL/̺ +:+לeE\xԻ0<UrnZ0Ƽ^YTPOWOr6L+[ P$Æ ^ &y, InT.(̐ CHeP>U8]pAiÑD :&YH( ZDOEͪ]gLmjmߺ[!*gH~GU2/B,7om8uE6hYyLord7JCc9\['DYhLҽc.*Е!ͼ( A?DR(CUXzfC ,<=3} ă \[ePi  n4OqCTK ]R6LjZ/Wsyr2s4Tr,Nv4/ g}Wv͢gΎ麽-wPXr z*k+boWy`j/dD왳"}LUr]t/4 $#Coo<=SV6JHGbxuvtN2Dy=ບ%ҙ`pWƼu-%LwVñ]}H4˯bPxaPk9SJG abPVLkf?!բkC380ҚB M e)Zt!A:B힓 [cn W,)XV}3RbjVJ#9<MA'z<ȣH՘IWcĪdI#)*ז$t\Y$K1JOaQ}EblksQ*RІc֫H !#(ގuX t'b2P͐YBYw] I%\}QLv95$D3|%f:9\lFU@-]nAU:M7fcєUC骛FB C'opfOW3G>l*398L+H~*%ygfhjBՕBLi!t/jZ)pΜdP ӵ6o-7@ 4ʱECus絯}mH e4j{`dbc _Fyn6̲:ۢtBJb,l͵Bϡ%΁kYq$$fS_G# yu}l*QTъ&?e{~ΓwziUtWUC{&&^Q1p'v ɂBX#N%NkwTXv=wrmsbyu+ Y1®snSɊzq[,g^rGU_1, JFb;Vi2lw<ꀒ\C*30^סI0uJ4U bQfg @t@3YsX!ED3 8\ءXt!<{]/>8,ix#CϠHPyǒzU s&Z.oQBbancem5$^ypBoq0BDfRy_e{m13yS-mgBuԁR+t fBpo ӠZBko 9E<2kRx|cFOw50a kcKp*L;+qS ͖l+" /v^URS1b: YSI6EzUAv1 jv,kzf|a2%8\' p~8M>#8*yUbn4̞6샐Zq"t /][ &ZV0c M7,!ƕLE8EN}8syM1ѻ{|5U1i,l2-oj4:%C•0RblIp *aQ :)x3"۔FM9'!SֻوNuCũZrj> `e% UQΚ +p2Bl1#*6)&$)0ov2jbVOhW ں2|0A#=6ύ|Yej&34citJY e?=lMH^Q2l:`ܜ-Pz WO bgTHlK)`k5`{F2MFlU\5QM:k? !f_Ut ƀR=AGn}q._q YhfmHFNX OU֩.JOr؀H<)pJ4KJ]cծ%u {my̬") /l 2SB2;ڇ6uؓUZdan22iLYX )2n>̕ 0qBŖcKe*}= 2VCd.߽@KHKY%~\aΦ-bQPQ*B_d *qrB=p0k;y P'&=#u*)h>2;7Қ<A?.ʀX. m|EShRX"PIEĖ~ah~@HHvJ a .(~9ztEn~V@XMX+=a60}3wT +&mPR%hZ20t[ u.!lʒ 5[%(@b -$'{t4]fq_!>urL! `]T%R^`w R؅(~]LS 45R[kɐa̔vU QZ*mmOsJ0NG֙&N+qTF0䣷,͠4Xᤉ(k!LWNHJ }Vd,ĴU#(EDh7Æ@aiY?v0CIc3E n6Sk>stylV N4yhBoMw!Я vjvjU|ə²*䤃]%\"a0‰kiC07pl2D}2$G]H"-\-oVs tB:ݑF ?)S6+_MA_:ާд{_ fVdeԸvHdi{9ȫ:ݙH\ ` ƚZ'45:sTD T%'MdDTvJ Woњw60~9~dCkD\X1o';$jOphAWԤ1Z@:8IhStx gM6_!5RBD>ې&v?Ugv#rNAU(V(mHk֕)^VZ].S"tH޽eFE’K^ 9~'泘v1bD m~(s^2"f$%/4"RWH vd진Q|E` n:!\&(%{P2>yT 9 بί;3B!Y րX/{/ ՗`^ု{_*1>l7-.f)gQ,7pPbeLnao LB6C ݮ7>-5`11+{mFDu]NP;ș"6eEgR3l8~fEw *[ϗ'+tehew|°&Ȫ 'tc,|PF8鐡yFg筎HRa(xmh]"I ̰WNlu)b˜I oxTCgd.&cӵI3fe͐%EMvBRhUj58*Latt?%feA::ނ)lmxL{RMƺׂ 0#2U Pא M;ڙh򒲍!oE[Fۼ)Mn؀Tu ^ }NU@> m#lY/ Bpޅ"yJ \JAd*9Ya"t&vЖJ2HdlPX -efS!)sR}(w(]f-L.3,*ZY*\oڬ[0H((l*Lz˗+W\cAaB|h~n4ʁv9, `=Z2{=d `+Bg@~P)/ ǐbe[If;ԍ(kGTr:wK^X`UʾkڶoTJ͡:agQNyHApC^͡;lKժ >m[fv$hba3T!ק.X^D΂=юڨ!#IDW ԜP~i< ii=$]MAdȡVzX.<$݇\uZՠXvR+, 1R'I%qJd(33 脛RqUJeY#)Ѕ# OdeJ:σEy)VToR< P K@Cl6]_N4EӅ̏gJ:ua}.Ꮩ\gUKhv T}*ٰ%3`,btT^0B'ܐf\Omw6}fUvK 3JQ塝 šR@w9B:q R΂v% #F wQRyP;/_K&-Q?#^ZFt4:Y1ݢ *kty0*?gʠ;_W*tm nVM8ނظucKanrfmXU񐤅iNU~Pjfl1ĦdVOC--S h$״Uʉ.۠Cؤ3U.0,2=Z•%LtK>镡K?-ls:'?3"73]>ݾ"~;e ] TڒRZ#muktOK\h C%9~WhYfTV2k(|lVa  | &6PY)# [yԳ.xF (y=BIYS :Bbn5=DҎ^VZ ~9Ry,dQ LxHy`7Ơ1qMuYYuMF֧TLei0 I$D2*4Uؠ=zSPCQ:(,Jb j"UI'lcR(Y(g: 2Xb',j,12 kE&S ;k3u1ёPF3́?(o6Faw}uvצ7C>\yFՍ(:¿Wr\5 ppE *Wd3dx[_*p&`SP<]ΘV{!2)W) dzP+%MTFܴS~ueaC-B&e@aa6Jw|&!VLuB^UMvD(F7zٌh] -B _!aBe]Fa[VҥOQ,V `U4(}ޚpft<<@QVuHtv%cw1TZraa4Ev&q uW;壶6T\9K:`Hרpa<, J'U;ۼ: ztc=+ց*C.3|cʄ{P2 ](X"uXxH% QHQ}M8){u#L!+(cbœ[WQ3iڴ!Dt9:SQ*P!1.Aj4;KDrJS%QSK7`klpe~LZZ !DN?y[GeaGE !F[DM ^:l.!co )Ep@XڮJDa$$Mdf{ُFD4n ʞHC zmn^ F}7`O"+-L2%oҝ“oI'(hx'5`8^\)ђ PU:T W$6CreĎ qqEH^x͒w] fqU9ʃKNAҎ%)(9{6 =Ҹ\ *o,`hvbpohwU|._䩯QXX4!n( _I  :^#4.XeFܳ92T)^T0.czi߂ .jcnEap 2!L5'O (q%.Z@!'ʤ[0?ʦ&h !x5 0-/a#a iNW1S^j :dkk?(kHC&+)`a$דI>eC:Yxĉqdf'ew.8UqQ,_ hFg(͍P BB-bx.YܙM8UzmP4ݧ0P_ Ys.93⤦;̪^l(M$ɣBcUNVp2/RgY/n-ΘT  N1,8XZXTc(,>Wp,Uphkd"EĮ0hhỮ%\\![0aŇY5EZdW :^$*qKzI`UF> ʖP-pۑ2M UZBF9ULl(O|ޑPlchRBB,3AT2v8u _w{ausex&_$I fk=.ΨfAҌ5ƬLwcA%aK':$ PAtjXl kš'ԸkӒr 蘸]zBg20هCxcZQL^@1m:%fvCV1++:͓E2צ!ץ}@c|1ĞYu$&CxCwBnX{KE'ש5l]Pк޽Dj_|ԃbuhzt)ÌC;cD6Fѵ&' K;1>bBN"ܢs°pT5B da"MR?|pz=륝,IDX9C}r_Kފhu~ֵ!R`C5jbC5zRmbnB}DSJP/PlQC8eșpE6\ԛ(*|١M X}K8b*I;dO~I`S&Ll tbIGqQFz 6sEԴ&5Ü%#轕> ÉF=|=:,&`$SuOStCUWͫ3&tHA3*uy\~< |M A~xBl"ocH'r>jҞ,@h|&ZPPf9JȻd_$CtQĈhV`_Q 8jP  D aGJgbOBQ?ڪ}6Gv<4Z?>ZLXYz@=a`!g,|]Aiyls*yC{ge"GY] d|-8qGf: C耮6Jr ZjQ@k4B:A0u@5d<j‚i*um٧Bx6$FIBh`ktb|#\"`d߽<.qa@r('Lkv)UeཷLjn`+5qRyC0pqtuУk900av@bcדGAimY7F=,6a.V`^g:#*.S:05pRz0ґawh3Q[ǵ)P,ԁ"܎*M"[cI@f䥕8DUwHyrJ'XD6CBzH5}r+쩘\}S6* Kd9K7T8mR-? 2pֶMe@b}wzfOΪ< &򕍞l`U4jMZ)X%Ihv;p Ek8Kޤ=b!  1#"ô"yR' V-$]f~_vi{TK!4+ jBvZo[yԬ`":Z>`=d=uEUc3j8TwB|VRd%{œp04Pu&wE0-]fiTb&zS;UB&)>~HI 4(]QBSRH&D-}-.>+kUb(7EwRiP2: SB)Xr޺ P4eP'}j1`V/J0/'7< Ke9*jj.>F kVe%f[WնtHA IymψԷa3n!˿,*û ϡ%r?PP@㒇fwёuiMz\X܇A+T-j_'~ [Cm0}"jR[Z6tF10XTx46S[gSBPC3Kwpq*v/p _˽*"F4r2m)s-l ɻ*9JLa~`PAD =_ gмVau!ME|%@*3r zq `%00) vp-ކ"tDQ{xmj} nö@AyLOS"2di[[q%:-V_Cn#vM @)֭S-t~J,(W1 ix\|QXb&g^&*өV9i%iaSZ56ofp!0LNUܝQfY@R2-wo!B0#ªt9pN q"Fך̬f~lBs7_0DE) T־xl=iG$J-*䠎5GpD`SG+!1bɍ,FQ swA{,|>\^UBO O*t+8vWnv( u[U(Ko6ٓVͭ;gfsWlBۻKc-oOI;ʾ_cy0٤Ss 38WWauu"|E.JW3ԣ:~ek8C/TuTcI㡦d h@͵P!Bit4тmY ?).my xGw(ZUSC+Z2D}eRp9F{Oɽ,fuy[;꼍}hK7+H5eh<16SDH᫏'Zo#F{.J]n6 ! m ;Z!)̵`YZl-2^U.&xRCh㘦f4{cY}Т9b`ehXP% dz1 lsaTP4#cS|u=:$s6yœoVز6ƚXU2 U]c!o(-F._c zDNY{V &TVP6 s0I jU׃ꖣ‰.Uxxljs^^X`򖾣\O-ݧv^Nr =bVs1P86ڳiCf ] |̂v=vu~VWPjPdA<^6+$ԖCuN;*^PLU9wAY@3 ˡ2Ǩۣcʭ"Q:m*#o;Y* =l! hl3D9hʅS{`l*}?HDzxT šGJ4AF؊k*YeɻL>ج mZP}xd\{XgXKŇlZ\4hCW,z#J`Lz=]^Naa,Sެ l@%ۨQ@qNmBʴ2:qF1f@Py &.jR+KچՈE:&_( FVg[~aƶ m6=e vťĵbV U*M|QtCdCRb.{w$-) tPγ"k#E <>n$%2Pt*,.S|]/`{gb!Nn( L):w#֡OvM߬fjY?*5fuaz/ Rfӭ6TuԬG숼v]qHkPORFKD=˕aB&#d+<:&yFҐ!qmSD蘰JRˬ@EbPf>2߽6Z)=,yP m=?@8 F yr&K;]?3\J:'~oQmPl#rf\*%dTCmImZ>q44EqpǤYbF:-:cv!7̞XUp8n ƒ2)q*>wSfծZIPjƸP~'ݞ`aZHFйCf;T`S!ꭃѸz?#j"Y4rlV l N"uܯP{N^5y.1UDM>kȊxj&L2[j2ӱ""Z#&o&sg7t3x7h~.`ΣX[޽Kf0)zN([M=7FrO>LE˜Ӄ98/?-qO 6 )?c_Wu!;ljeT!Nhnmb9Ec"$.D^<(M޳ 񇴶J͗E˅Ы4O)sdh!2V`Y%o;2"Զv8] iѳ.FW!W/!2NO1Fj.b8`-,g[\{?@s$[bU(4J2X+4][t;"sPa[qu8R-:a3K #NtʴL*a0e=hK/(uN+5R;aMOF^n RLXpb$ou(lPaHT ^sQ T<>YP9(T ꫷(6GgVS†D/Ħw P&3G} "!U^P(bj'D0iOl8*[qcڰbV׽2Z5RMxW|Dr6˔ $UmZ}0ҮMP%멱4.;jF>Rl`,pD'iDZ1e@lgLPWԎasYbdewGQFhTBCn_BΆ뫗u"]| ae$^R,} U ,TE5a<<+F$g2*3lYyHGmdlat@DѢ^GY {`* J:vmh9^5n1mڠMˑ!%A!f$k`%lh& ζRylfGsM)` Tf|¢m,YK f!6 `a1[ gVhL`Spa2ߡ:bR+`(޶6L+ttWp`+3Gml`}ڪ6'>x(8nqdM5NYvlml&X6)gx:[d.ḅj&v=H>nAEDO Օ-ah^%Hv glXã83D+٨"uݢy")bώmrQ@cW\󄴮!̨WhLC2x,!G*9!U$E^,C~gdrBprGW io '=(m2`I?Q&+69dG/3luES03$a*#mnC&4,n=pUh,L߽1PZ v3P9TOYwA\Uh 5Zq[z6(( 'T9w/ rKUCi(2^FWANH2t@CW7 ͲU3E0(/ $Vl haxoUURI,,) FuRX(e#*RL*4aehĐJX2]Hi >efZTa. U5 .&"y5E\ա:غL?Ƨ{즍M5[T/31%߂81v||4[W\b ((zRVRqyJbΗAf~N,[h寒 }&_͓v7akJΧmAx?[0Hfp8}6ܱ ^e,gi!/,,8T4Y;z J>8^0Ug$gcܠXK:lu._DBF8ZzO|eq 70-KMzh~ADh/壼4#1hrc#Nw{G/ܣrյ϶CUݻ-ǥkba #PB0L M6{ҒBBSSe4.h_f!T8l`e@ TU9 J=eJS@ sTwcjoIߚtt_L1oMΒާcrpi_﫻bǂ{}_//z}/_~/_]Od _xfⴙq>?yXRl3~wf.ey1VW/a:?V,!X8}Vo.G,?ɑl$֌?MQ+qeJq1ۃs3_xq//WP5b~r^S12c.*nj {ɭU>| ǰyY_Ͼn-wAcY5{To>V4wU=:S(r:qwq=~uͯX{3ѮYi*'wِI?i[>ĝH/}?OyTjgҤѪ9촛ږglD5V^ҿOl@.0Tߋ>L{_@WDm}Mwj%7࡚}Yixc阮WqO mbX7 J3dyK`o]l{s5{z}nI>g9V<o2] vC!m+wIJ۲Y;3^-}jIm[69ϪkN<_{;ޯEk1ޗ/}C@~Y ߹} l|oc}Oqc=ɣ3"r_?>חG߬z`wgg7T@>씞Ϝ1_ 4?l5pgl:N~N_5u~74=]ƚ8efoϏֿ߰wE,CQ|>d?(vw \m '׮ms37wx˧y/o J|k+ޑ*C(}7C(CTooƉ]~xPC&߈o,M>SW6g޵|.?u:5?s:,jU=W蛪dN3Ox\bIxxPe: WcOW?]񷧿dg.0-}lA D|]?|_ׯ~_ڻou]}o>ϩkrg;+yaU]W |RtRm}mFy/W=|y￴mh窗{ZzOS';W-Uj9oOOIrUSmuK6}F6ڼ6<~/yhyNwye4ϣO xU/h6ںv_z-}N:'[_/}'鯿Zg]%>ۛηO媗myK>vGR5sG;?K/U/hmma}mҼvѸ65=۪r?hvz-hʽϨFF[mʽy/W=gh'Oi>>뗫^Fk_i^frhuz3k'[+vw^*jL<}>ymF\vی^frhS?w3m}mf<뗫G;ho'Ìh窗m~~gTnh]~ys }v.}<>hvzFkg}Fϳ~1S6K[ϖ=aOsyO\dO'\ďxN_pnf2뗫oOs}=Q?>[ٷosݷ~k\d"x5gTn2lGY?_:ڼ6oFϨFђ :dO'Ȱw'w^j n:_}nU/5h6Z\뗫^Fm{}QFTcAn~/W}+Y!{'6z򙧹\Y~73O_gAh>HG{Q>1f4oў6߾>G͵Ct{~\{/}?F>4 ctzk-h6=y/W=vr޲OȇUߙ^μɬm6{srk֖_6>s]ڹ['zkC_޸K=uqns?WƝ\{oק \ϕ'{k}LJv?/r8h >z-zmF۷9}Fϳ~ꯋN.=׷S~\UOROh >r:\yy?'cL _Oⷾl-=o3UC~Yhy}F~eqmFk=NN=[)e>ڹe~Fw媗"~5wgoh'-w_zl!k=\dmyK>vaʓA-wy??}̜o3zU AN4q==\i,f>\m~?6O'[F)kp?}Os-m|os޳\ϕ'{k>1O5\~s}~\ߪ_*_8W'|}o֯}k{LJ~^dO_hLoOO\ߪ_*gk͵Cv?/r_\m6{~?6O̕=}^1ϸu\J>\ߪ_*g\׽r4Zz~m/6uZq{~;O{oOՊnsݿ?W\<>:nr/WuyĩZڹeqmҽvqQFz85V5>V>3ns]q{js}j|;r+I[ߩ;0p`8\ |}hUժ>-\ܙk`"F> Euo*3k׭1 浂W$YD;yQ[Mq g Qj+#QV+<^|`>x %*jZ'~ݛOq{UTYȧh+א?u?!kH>0z_3xk׭{k1۫"F>Vyݒ.p-`^%p&|x nI!W%.0^WKnIh"Mk^{59W^߫mkFoQ'*sѯFckES9ӡoXKQbLM(g+HfQL|c+5W]ϙE^k7lN̢WEE|zʫ[NEPC.PZlBMr7g9tA-}>{ e^ws39(& 5h|D,7&fl 5*nQ6؜(Z1Cĺ[28YRK@ :Y}dkH0^/nUЃq9TuD=ٯ "]|.?{$p 9a>>^ws39'Aلנ}l9'Aل >a>^{UYl'עɄj]G53[V-N&ԂnɠkHfQvLxkuo lܫnbsF>7ёAلWl9(q]KDӠ=(SOݴxc/ ZxinTlp](A-rGttZ0 h #:i᩼j" jiSwuNȼJ"LjuF=دf9(vŽ ⭦(Z3k=xڇA-!E/>yb>F,N$t&DG fW[VSLYp]箙E^;b>x ~gZRK' {k'*,iSůE/Z5d舻QB-ZZjI}^O{fDuKwGµz ]yLљ5޷xUZ+rĠ,Eo):;TuE+n1@A !:@-j EP˿8{4UQAgC#箙^b>{ kY?}*3!kV^Mn5 Gܵzk7R,L5 >x|xM+ yT#Y;"*5/69警xT GfP Tp-Z -!SEGԢR> EԃkHd1^UVgY# ^n:ԼV3*8EsgqQ5dAyu7ejZBeT[|VSYTpTڊ5[|yәT7zZ5舻QfS{UY\ȧ^apMG,7d^3@Ww[M1KgqMQ%1^ny),i8ʠV?&k|D";1LURMgOǃh jԐ]#ZD=w*.,viS{fqDA #:@-j EP˟&Ȣ裑O^WEZ5舻Q]#2| }|xM3#j,:>2=w,ȼzàYDIL<(VACt](|b> ^M̫bF>U{Q$kM1 zս&WTәEPK6&SSTYp]0נ}9I@ >b>Fս (SSLYpA<}'^%u&7|DwͣZ -!DG 2M t4U6&^#xEv\ɍ^%t&|"xQ,N t4q|2x-x'j^ <;2L5$Ayuo*%P˨6)$SS\YpTڌz {Tә{-)sQ,Nt4PZ[2%8yTˠ%(ZDɻ"`Τd%*Uh)ipNDW6;|͜ (@-h5cNk%2eh t(ZTjߟʫYs:+ ^ {v|͞iGҵj q"JUPQjkvv93UZj8+CGyCmΐ3*tA-ښ!jjdΫ GܵjԂnɘW#ZD jZy: QmYn55g:V[{n%%PÙ:EPV%頣j֜VSsc8ZmE jp.Pڜ059g:(ڌjkqy9W1q"JP %ck%2eh *(ZD&V[{XK73#ZD 5j^7:EPV j IYWUo=_8#\msk8_|pDW6xy5Wjs=8&vDW[ju?C(@-AKXϣ#jP9S]ϣj3ZVSճ]a_pQBZoyZDqUjV7yQj+JP <:EW[򭦪gV<ԪA떌  "JZٮёhUP6:EW[򭦪g6UZjXa s$jge{nūYe]+*~=k X;<=:h +tA-)Db^UefF>(fMk^ 9(qg2: AmIrAjs5/ ]Zvͣd|LmQ%QXȽ(A-떌 1A(6Gw{&0eP+ݹ |?t?ߜ!?!u؏{Яʟ Zi6ۓ3 Xˆ#*O|xxПoҎB?=NU|2gj`:ݡV;gcj;W ?_vzHՖ{{0a~68K>xtކ:ޘn>N9qZ1p/\6ݰiYĞ|k3 vL;Ӹ2e9^]0i6ZlP~_y?i@|So3;-=V-nV/wmڒ1q9ԕfi(]|yz{q;' * s6C['#s[m㕍ŝDžTԜa+}&qI۞uyNDO.@7lyZ}uxP=KbCsۜ>d<[-EEںxRo\!7jڽD!'.އȭkMB:Q&:3{YBnSANb뎫4'UTJTdlkm=.hqeCo~ĭkeq:죞[:w.BIuoJW];u9!͝ҳnucI FVlN4wx޸2Gk4oϧM٬iZ.;P_cASg=lV?B'S;~ʽvn3qf[6 l}vCgI+{$4l %!]64oxig(;g'.['dr8lqe"|Piغh#zE Mжv# \.Z[yM^N[筺#lM}1Dn_uݡF4^_6[O$'zQf[8^ͤl9ʻ?WΞ5mu"k߹ehDa yʷ{uWVauzuμ1&*x`Ŋ/ڝS, ػc{I$Tڛ~͹LFC휶nqJJ8֜'2;|4;s%(7!'&j7\y{ٽey'38(HoFβ?t޷f'#7{sߪR?q97;i֒Zx|+~k&^5"*cΟ{]G.2[e6;Rݿ; Z!I }_uy5ۧ cr.'99~gϯ^woFh?M}W=iۏjo݋|o'z{o;PB<طkG&|UCr3;ZC1}Rs5>8~"Z C]{o_h\SFףWY1V/׶Hh֕Ǖ1ۋ} ]GNhe.}Aە&KGooǮOkOEOv5>@ۃv_DHXY Gm+/D?7kUҘoɐoq`?W?\v%{ܶPv=hq ڶaiH5~Ie0]~}"V{|m1iX@3z?ME t+Ķ?Eo"Jz_!҉q}?mBg۱CMv}z99WFTT۞wңz?u@o]W g2зcZf2ҷcjzmQG{:cNvKqAe71=ߔ¸Y1ګsʯo,X[Ie6oi5r_8t~󣿑J7"m_O_U}sluki뇖2e\/m| dF}>j.r;3qO⸟ko?߯> stream xW[F~@Q0&RfV(n^<c7^^'6v(/u\ΜwΌ_'wZypK/N0ׅFY]݃@i@7$'堹Њ-L 24i)T}9b$4NO߼ 8eǁ5A{q^'!SqcNmÀfߤF?پ?RnF׈4QɹYN:1Uj}׻71瞝I9xj/.il'hN (ku2?SxS̙ rCn6'~z9%)4|$hCdlSs3Zq!?NG8+z3V߽gL^'1xUYyIDg)c4'eׇ  4LRxK8Ng쟞*paݞzz6 Stz]9~Cvc_{*Jn%'`G'z"Ls< 8PWT1((#e"{P)"^VU3,a-˞%ZWS݆ V0qqdWi \MA!ThUG&lہAmW‹]GI\Y9X;F9-Jʱغŷ%0Q3ˁ^$mIٓ`%*ϭ>K@n+(+ᡲvV/ V#ї9ueyTk!hũYmWL1륱9(62k)l`{]")息xb}Vqb= 88Ihendstream endobj 210 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 211 0 obj << /BBox [ 0 0 432 432 ] /FormType 1 /PTEX.FileName (./hexagon_binning-addto.pdf) /PTEX.InfoDict 49 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 51 0 R >> /ExtGState << >> /Font << /F2 50 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 20976 /Filter /FlateDecode >> stream xɮvYr6ϧ*swg7C @T%ŁxiHeZKBAo݈}DןO?_WQJOz~_|OQyOx6 _k\kq3}>?V;??y7oc{_oy~oo~Og/ϖa~s-]Y{ew:دtTK>,#n?猿{Lg ?;ާ_x肨?7+16~jܿ:;}_ý~*+Tt4;uBzf̿ꡍYn)z嶇2y~2+P#7_o~W?o_oO_?iߥ+wg_u%ף)[e2׿{e;. ԑwruWd!sq=?Z}?X+y-x^޲ R ՑcٯV>I?ji?]}k3~8\\>zwFՌE!};r8W&6ǏFW哦QRWs`$2018\\p7%F4A&sn"\DdoHTd=;Y]Isq=?WiooR^Vdʲh\\G x{3BՎ7GL2[9SIDMsqHr|ku%Cl%%d{l>-4mv-yl&"\EyW9Go}=lݑ7!6Nzv x<$@d$_Dw#imׯNUt3nN^DwnOz&Rŋ-;32HTDZ nMqMmHu:.ZF"{\StH"۸~o_@˟Et 9TfhrtՎ,}#'ue48WWKwQdH'Su~ NGι;%~vwpuH׹8)iqunO&4jDz2ϋIHǛ$W7)Ա/Pw.Eݓ!Q+EH~\Ck\&|Gz/"ԋ4\Y'sɗr.wi e_y#A,}4TۧWMp5Cƙ/OQ{EV48kRW+Oy#r.R'Mj&aW~[OP*4\\-W~0'9rxAzsi q2]V6릎"(-!6N\rD'Y'EDF͝\vnu0Q{.&QdNՎZ8g ?zve"~IR!bO@ .ZFPDC|ptTU| aWl:eZmN$"8'$Lv7 K9vbw]Uqdc&k4crSiF(ͤL㈎sqX*v}+2'Uҩ6dS)}}]hyx}pdSï$P{I? Ieve'$]ͤtarpqdrWe< ȀԞL5.jG5QhLgiPz?i8v<+<|dj;~wkF& p$s7 |o|R/G&$YPjޮyrSa_M)\\3y~?Ñj0C!8͚IjfЫ]s];# Vq C\©HGɪ8gwF)siԱmn٭^_%٥W "q.Wv.Az\/ɭۨ|hkiЪTw nz@[@yӯH١]Wz6]!8m:#>b|MTDv.B|Ns)Zh"O)$HVɛXT44np5| HZ~U2e"eҔq.lxvGg=MVW +8BtfzvccS9vmy2#z?^dv{@ w|1?P bhGcwr\kԗJ}JS&IS+ƹɼ& =m~g҆%\ӱai@Hn[C W iV,o֙W_v )y!rą}'!%+v߉Ƒ냫=9l+^Iȹ0Kð0K\lKlIOEg N87V U=T=AX*j )Z} VEs8B9[zn+Y]%@b%by>i=KgSsRBLbȀMN4LZ!2X'$P"H#\|&ۙ[hI sd{8',\O^Mds82$WڹĞwQZ _FV؜:V@xVV }Jw2[V p9i+RH{4l~[pm[zl.mъ3iYvHSp5hWڶs[Xtii W7 l~Ok{-"ߧ u7^eG r$ᕊʼn$Eͭz5X5%iu]4TF Zxv %l]F@zIMv0ɼ 8jr~kƑF?s͞s*?6iѵj'M;z^F-dV2:"'`HkhatsD]sH$rYPSuyEq2Dnl]ž4* Eh*fູdd'D8f>1RJq$f7NeHaR5KA+&A$sɛ~R X]$b\~%z#\l'Vd-]p}5 ]4 W޹=+Ӣky'DNƑƸ9pZ_o:foqSlw##\-lxm[ԄMiwP/;U4 szp-=l@"$'h,uRò5syv4l櫃 /;#cMB(fI4p$׎["O7%@⛈$fiZaqd1 \+`7F[b0Ym0JLK#k\'g6ag z+BV}kȦW\vnx9O\ fcc,gGbNfu[32in _{~8 jǾf>ƈ+ѧuLV׫7IZʎedG(+#OԞ5@gi"&E\!,f" a..7Gh2{enEZܜ+{n2 `@!ԅyGMdt=5mvg$ (cHMM\\-O 0`zɁzQC-YXSvբzf8X\=dMt]eG:mQB'®Ȕ^VN77' /UR:9(/ZҤW/\XJT 5j _44jW;&%\V"<{6oq=]Ͳi垐Haq'd5?hiq.%$;#5q 9>5LuZ#9Pc9Z@ 5U,7#Ҧs✪sVgm ]-'x 1+LqSv5*VwC#MK`4t@;$h@J1K}^4tjε\l^'eguEqp'H,![@씼O?˟ }T"#aw. ؙoHbt'jVq$ޤs'ȹd;D콄jMHڹj9բ!W{,48Ҙ\~)dոIhE0wTXDMFfLH8㒳:V:[ zBs7T]\9#4*Sqbv{lwq$*K}>'T֞:oSѿX=M3!.f1=r^fu$k&Ћye".G4, niಋ ,ޅ^Ǐ6cx)Kʼ?; i6ʂ0,;sEf\29P\2S8(BfXtE{{ Lz0DƑE\4*xcA*B+Ur=I&$G&3g5#'O 7U_P$FM_NT/{طKx}ཡblLȦmD~mxLLe^V)SMn=@>IXUZn4D~yL&B Ցy&NAA\N4LZiS1aQ|,@88oUK}vj0Am:0LK4JvHu]OX'IoA$ \9|&yB_^w>4ƑE\۶pdy9yhKf^S(8U׎}l;iXEѼigW>'au"^幯Ulhaurwۛ"6^\`>'f,)7:B5r9qقzu8 kbJv }g䉪yV+@}2 2#~!a݌ rWְ/0/ +O+͒1A2cZTǑ4]VΒ%n+*& 8\)X+7֑)ŖM[=&0&GVTro7 O#<a2XƑ!N [;}V.X X, 5QzcX;Hda K,oavDȊz KTfxO OڿoG:)[S}uzAPrL7H^T?8 Mpߩ21-qdNۮ^ҥ/2ՠ܋r+F9 )+qdmo`U`WؕYMٹNdދ.^}ÂHT?/dGakGvxz}2iy;&$GbN+%:߀LcQ3+%oZ#" x2/t ~L$Kt3uD?Xu,|~^ǁsM88HnekвFhm7Jo~(2` ׈fNMVՑlIEXI4@ZhΕſ}R$<^cGjp+g5R5!R)6u _|4kB)/{^ f/]_`QM4^ Rd U^mF^LHd\rgyv$׆; @Dт!l.h9nA|#~ ?lv]$4@Z/{梫kBiXoȋR8s$[LC$kX{B ܕsM=V WUwc"B-Vs~Ƒ^kTiyBF#%DcՠՋƑBzM|7<6,"3#lu=['_ HadƑ. q5gGm,hَ;uK߉Ȗiiѡɸ#궹Do2z'n^k\Ŭ1HəllLHcs*>.GEB Qӫy3#Qйd/ -2A%,kىP?eG3*뚓boV- ڹW_'q1Ƶ{3-'R;_;JoG"\=ijԈDs5lY^-28Ҩ:&),)< r(r3 賱'\8`WO$ލ@"h3&U4&pvhَD|=9e4t]RpȲwӴVmV*Rღbb"U}ŶrB.~nB[gn&m% BU&'`"6TaV"(,$%UZV X8'y-!Q8 qKX?!B#+r-f/jN}4/8IuGʶbQ+2uW^Okik%)Z^<LgvZF]+4jP@&+wcFdV4\9YQ dҔnhUƹve IW ȤEl~LHxݲPbdR_!ė$WBdv0 %v_"QKi40d\)[TK8̜Zy [YX?nOx͜t8P+̓WN @Խ#/]g$MD,r[U#U~l`inq^5r#|@fγdI#gqFD̶hy73Q=q$+2}gdӶP;*l1'G6ssG«T-Vʦ [`ۓ `F0[5do\uKtTJƑE) ;Wx}WY9MMC\;DwQ q@f%6E嶅4 +MoG |׈FJ!ݬ]ei,@Ξ^1*c(&c]1*8 \γȓ}>˩4&N`cu5hӳ= 2'i`SܧVhE6CH|3&L-ƑckN VbNi W>X۬d2FcM=X>MrsĸկdFn hijm[vȎ*@X_|2dbliV\;eKی%r-5+_7sqRހ|Ldl]i.  ׊<.qcB*|lױȵ"tZ@a% ~iMSLIXR%8Qm saH *t,;|] y@(V4h^vV% hK-xa7L]$T,Sc^tZ^%']@N{l.t'EIcd2_py1r2?)f#zq]HxQ_o'#^\k,I ̯|"K_4ŕr] |$SaULixށuQ;މDdN1L34tjz+{TR#FcUf4/GR/z׵Hw`=NN5qĹR-Om;%b>f!4ߟ={"uxbW&B@j9`/GjZlx.%l.3FdC2cTw!iI1"գz;8 LqEFsyY',߾wF,%]ǎ6oa/WޕUJ3Ӵ'MjRiB_zg4gۜK4K G"h:eixr.s~*k-aS>u1q) Ԃq.K;lh XPNl`9QX2k׹N\/rbc,)krC`nv4)p V=:[AԆa G )Xd`1tA}6b}]tf Q1S(bb\=jBls/3HN<ѭVذPH2KmJk/hJ6mjKF!J'Ux>͊ :)Bz8Orٚ9wF K lvєy]\+Ex6a.9Q۬vi2#%'׎=jW0?>qgOt^BQMP\W=;#u#vªn:q$@R~GƑ'˭}#1 ,žip3ToHԜ8RDʄ7#(pJ~-E)Ue˷s4g (:I}gہꫛx-Hkfv` VQ)b@CzhtoiikG\1]32w#2XLZiYQѹR|V7GXH>>2'bpMf`=Rz{?aԅUt9,yTsq" 'wF!^bn:,M_BWbC 9˭QeM̈́?R[3B}yUҟƑ݉+KK 5 &8 d.60DJ{ۈ R"2Bk^Z?i\3-6Z֧굒qF7rS(аi%e/]= X(\\:YVhP]dױ-PEp8K9am^I otA?u2@.`?xџ5KzuPq6GьL@GXRMnEJT=Hcճ ^4t }UGyVIĶ q|r|k,HPpP[t|O}'`"ʪ j\MS,><B l]+YA XJz &/ݮ-CgwLP8&`YaVhrX\~i̲Ce4'̶@|ެ2wî锼G!㵛 BdWm,O֣ M#+r+wn\ T@$?&dzmv"+εST'dW=B"JU ztSz.d$H]/G65]p$i:D FGD?fH4Dι>M9 $ =|4ĜN=Ks2hZcFҔߋ$Rd91YQy1&orn2l"mN Uk'ZA-͸\N39(z\:$ZRg[dDH<킱s$}IN7#1M\b?я+IGbk!jR݂ /G VcmR͎m><:thzƑWs$ /\f{[EȢo6*-:bCz{u"|ԃq._֢6\CfNx%M̉vsܦ) ;Б6m8ɺ+&G&5]pTmT^LF{e;jH7#=pT; #zmWCoo&['kN~vDΑN_4DE~璥W#OՎD&qniBi8W,u뷿oLa$|#]s.G؍\ * ؑArhDM3pn>iv_~AS85/1Wv7,[K%Oy̋jf#O{`X)9Ɯi0- #,5Z~4^%"nSG2XЮ?z0IHգK=+`# 3pW\4W\<݀0?DEfwW!L#KƑua=4A f.k@I#aorWH ԙsDSl-*җIS&ƹjğ Yjs2un?qEFrN~.a/w]Y}q!%Z%n҉C$f[Y44$pm}{Z˶bMG%u…Q: 7o5uܷLf*gIF[ƋXlMX#]p`Ý9uM^G~[L[ebu g^?(j %wj-f?;_9dRI ƹvTOϰQ& Ꝛ'n"+&6DҮ=b`$E6 )rZwՙ"k')`6yޅ 9D =~blڙfE8j%٢g5݉Kqt}-ݠ;k%ʽbՈY*-:"Ūhre+ n[Y^HƑj+*NP!ǑbZkًfۢ"򜴲yٽ]f.Z|5z&[:ci؉oxuЀSXA2F': 9LŕRܴQ{8º6JT'I"|Kߤ!flok_N_ [hؚGV;rZ)LqmVآlG>_sqT)v k)&mF; Þ:a-FNAGd Z5n}\k0I1Kf3_q$f ,Y:Z8аKY[s* OBsXBDc+FZ8 d1Ήwhw}DL9WFY4(v`ք*ʆ'ա*-qbAM8WԂI5/dT|A"9EܿC&%XC!r>\!Htu{dOqn$G&4A,DaA|o4tf|+0}8} :Q^i.G:!Wcٻ~"5\OEOGEmsj pT\4p;$WtԈ7ɧ1whx'nEwv5Hg`T{L4`|s3n]iiёHy 5Nމyl籵hzsچ>/c^hME4D ]H#y7 @"*ޚVhJďDS;ƹZTݶ RH=rr4YJzJ,恻Lxv7ձD.y0"Xb[jp0YNLSE ɬ'm3烦nsqԳ#df@%.թ|оjys8uR\{$ft;{wnf@bevVpVGiاAL󣅿r i2W=O <q) ,VdI(a@?jh (2l6Fb$ט2WC=K 9!q,~XG+Cv*Fڹ㈏\'ec0$FZ\2_MYx6ʎΕi$aIb׸LCY#5j0I$Q2T{=b{ 'Vtx#cFH?ܿlN]i q2()hM't$uŭVI;F:׊Q{";DwO7t8n:f]ɁFN)OL@tFrtcG*f01f%(`XRw rk}g6Ii,ƑSn"O/#[,T@D'c~(2kD'AІSGhԮfT4DgEHE\-æ~a 16te{.GX\-EC{b@EvJٚh*{&vw䙟홟 H|7p4Z h ?6}ߚAȓ+CLZYT0؄fM)JC0d7uK⨴>f%|1ܒior:݈F!KA4+b %GOhE}%jhhp/1.sn+ǧүt.ZXڭ7"~}pNG_9v`ƱxUi×Q`Du6ٌmZhq$ja | 5 ʦ<"[Fhns!~5Da= 3e"uuuЋ&x%':"'#XގVҕ^ $C!zԿr(\5"OOi:P$YA/ {Eң+/hW9D,g(,#aUOc9EI_4DH29σ D._O1ܜegR:i.UsK7"39LAj|7 (IS{wSf 3D "u}(9p<0T*z8=$+FiMH-\)~A*̊,v 31R7ę kl=}#&餃D7#fIaԇaijVR^B<JN )PDV;_nq ՚x }عCCMƑyΕc9{9ޢ}EzXkdȨKbP6#FS(.GNԆ2Zrď#ғn/EcZI!M=*ʅ }h##pS;}lJ=z&?hi5ŜK*[NyMu lS[|(B\3i¶^6'ջv-;3kd׺!H k|j|!wi<*=ہ԰Fn~E=˞$8=ՒhՀ5S;#3,SJn,ha9,A<_BC;qOi K\3VH^GW)AAH:-?~?_/|_Ͽ =OO_TO?Uբf_6*YZuɖ.Vƫ9K#ɵ⊌-ZEM"%6>+64ZD[:Ji8l=2t4 u+٭e"{s+~xpiY-}qly~f)N!6NIKJ5j:;Bnqݍz~6mM]MH|ᴒvqu\[KajV7?tͳy5.onClU[+tUɫ=vg8v7#z²%ck3K;'׎[}~%C 7XoS.48K‚j1+5W#U1q \sDn|_Dzr#/V:Q{1ҵ{iuƑdpT_cYij?N+ت'E|sGTtZ",aJ>VU:O4 ?|ωWI_iۯpWݟ{*nR_>W?QWOϿ}k= a`?ZV؟ٽ7ա}7 #믹\+_ڛ?n֮S떌EmK5d`i߀-/?߿*:_VZOC5͝Ƨ*1VIUe=X"D@Z YOMx:j4uR[stK "mU, ZRm&ȥI.XCzn/@xo/l5n6ݒ:/$ppMKH $d9Ø=nd*"2n]8o%L\t}&)xk/]]-V=wzVQߞ݂/"xgVY4y]chmUULr*y54x?S7m|[@训h vqU%L⅄H]}lZKgA[sU{MVL/N`Rۮw4F~b*AZjAեUhTx5^2{.wiUXkVE~7W./j=VQZ4®V|W А uDiְ m0hjiQEKk4|cC+4+ޔ=M3ԼnDg.]4go^^3@{춞5#u>jѫg6>{vc1tP xޟ>t<۔DF {>}ɞѫJFo3AK"{z zD]O>=}L|t i@endstream endobj 212 0 obj << /Filter /FlateDecode /Length 1121 >> stream xڕWK6WA2h&mMo^l$eǛK{9/UB֐8p}^<>e^$z0TiyI*޺>RrƉ}i}JXQ]';Rq:4lXvirk|#?1'@xCv^+XX4[ {vqƑ3N@$Y?]z厗q?xq&y|O//AVw wp׉u#VŔ=F9N}u']niE0Q6w qqNrʮ-7ZȗeMG8_^hK|fT6e$LU\Œ'?4KJPWK}h߁^ |\:⭈}QCVo,(aTrx_O8^{$oIf;PXr$fendstream endobj 213 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 214 0 obj << /BBox [ 0 0 504 288 ] /FormType 1 /PTEX.FileName (./hexagon_binning-comphexsq.pdf) /PTEX.InfoDict 55 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 57 0 R >> /ExtGState << >> /Font << /F2 56 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 10260 /Filter /FlateDecode >> stream x}M-+3;oղ-dKvjyRm{P)XAͮw^D  H_z]/W_׿a_ϿJxU+;Wϯ?T$ Wz#K~ #u(jN_zNOJuYIz?)W.?- ?-Dj/? _[W_r׿]_Ǖo(ꅕ﫿hOsy5~Y;)_w ]m8X^,^-//v_~ U^IaecnK}j[{bQMF{F ?wTQ{*CxsOM+Qu{*K~Pnu{(''NN+P_\6Eg~χ̝\T˖ʫx/Qr$I2@̚jy)b9 P/"fMZgȣ(bTah5a4JGu(Xb  /n/&2lKF'PdH>5bpXaK{;ޓP&Dh695A8'dL dak嬥4e$QoAE1_^Fɇe8B껻i2.[^t!seW6hKH^2= y 2&[Jfm wz'af=3"f;veMoPd1҄9 +)bw7Bs0kB: ֆK}3#o?b\Y8< {6]e`@,|)ȍ2|r gEeSĞ[v.[&r2@le+íE0Gyj^yjԼT 6)~2@̚j1i 7&{c~\3IlVVSέYgP{Ok:4;0Ysݣ0cDap1ԅȩHH? E2QKr5".EZi:6ao{` -:Y5®㎐QM̻$#Zsc\MZҨjr2PMB< 5 jIƱH Tr59"\MZҨjr!#$\M1nl@S\TBBe+Q&vGUɒRr{DMF5Dfm )>elk*h ќVxlDAFr z25bksYI @"}a-$6PSIsUگT!B4Śu / o\M.ZCVAg5<ך sgX3?ߌ݋up0o侟2 Y8YF+jQI}'Q`T̙X[h$t!)loC%52 mlk9krC!k2@ؚ#ʼfTP/c1$?m ^VnWa9C{]~"V\bk506.^F&ZΚIEXM*!K]\MƾF6*zne(V{8AlreÊj\q%(KV:Ȋ*@l,JBڼJn]Cw'/#ZlaX%R|S-o^^E:UfQWq2tvLkzVU)IEߔOuR1fѧTN"m6`Y-N@+jmeNZ]GȚh9k%/Q<%e %E^Wt2c,i3xZ=ͨgdf%JKRbC("S}l Qg.6 7#qV sn+?\NHZYƙ?a>r"hs½b2NACZ\&3գ"V^Vsv/jR&Ț"Y?c fMuI{3ur 5Yt2c d{t/o E֦{'RĬ[ѵHEVkXy%6*HkUZ^L֪s/6fZB֠?s1q'zjqȲ<"Q|ksamdIHBh)Ӥy"^%c %^"'T%U٠pvy#%$JPԻ 6DdޭZܻIՕM{n9ekk}ʦZ\6 kXN8Apr\YS-V}E4尥KȴŐ -EaGal K؇IUíngʣ~ZlYy$Q*dY\fy}Ukm,^Hq$;keCš"m +;ee|XkvDH{֢"vE+]ߔ.&rɺG {F,1iznWX-)!x Vr59,N$OK;uIDat8-sg^ɔӝDG,lb!nm"kf=:k@8'pIVd ZZ1мDpI&M'ļZKKNAFݟkAMrjkwdH>5vܹ)bϭ\6geX٠6fd ZThPq%SJj%1G'ʦZ\kQt8k ژC֢hjI} uН@YQc ièVYSr֪$AY[[ 5e5bkņka{6cgMm+,%ElU Gl"a׷mN^Hdh:GHIEY&I2XM$v"(b J=;,zjq(k l=rO aΚnﵲ2@B˝Hsu,Q pVKƌ2@l,Q-KjY6-HkeLaگAmmOMk6[ET=(CFY4(fwt Ye Zdm-/a 4ǣBV5*kHNb]bT[ߪlm lӴ$7Te LLgHr0j,+UΧ|Ɍ cCY ^BAJK3%4;}${5s=*:Xʇ>IZQ7#Nʃ! t"5Bl7F:3eC.{>.(b1|OR·"O!׽n,o6 |IS^]Rm ٘nXK7,HZB.W3we@` @+9DsE<0=9ڜߪ$wpZ$Kߌ)C6; Ih9r"֗![便)b Z=2d+[nI* Zlǵ!r#{ y2@uܷq4N*bc 2eK{$t=[m,.,dOi[y]M*b=Zv 5{jR&õQ6; ާݽ2!qٶ 'pwc@Na)2@9[ںûN J, v {w]ZdVݲ> 0멤k,$Y&hezk -KISJEŽ `m'`uޅe=VoQ)bmKwXjqEwIE`&a2@&UkrkIx[Ln+LFjetDWX-RMN I⚜1 T@h?7G/8jeat{I5,p!jR&_AƠ3lxe=VSYu]->Hx\>Yd3eO$NҨl`4*.lDGeբQYr@p`Ih~N'fdR*XQ#d nV~0y 9.WVT.jua ʥlg+~3R$ʊH2@^V."R7ފrnj"L\4kcG!k`Ef ;,KuikeE.WXFn3h kyJ6}Xbw=AǔK1PVd^2T h9/svSDYvk7)U4RVTidZeB`E6(bㄲ"K"6%e@S= +e5zۛU.:K Wh\*+>JiAW'nzPJ@({Y7I[cJtؽ3C!'lLTY䍃B֮֠6bIIYnE-͌'ST{[l3yodj~^BE``vw,?OזNWY^}H lX^&iv2S3IMF]]R{&^Y&ҍ' V oɲtkmo[[qMU[M*bljrnv/jR+[b9)4k9L2@̚j5nCMK`p (bMaʦHzwe W *䍞}Ka! Q-T%sdjvGrEv%H,@%14t쀐9l;Bv|k)c^ llk9krjk5952@ڽfiԑkU;i6X^H4ĻwMkWw {\kXkrjeT+I' <^)bkZ~$=teh}VJkQ~$T>{Z\&]Ѐ{_ְ﯉kIe9~ZOΚ"[ր5rf В(kisc!$ڙh%x?Mkp-j7잱 k7véQִk5952@ޏ$kXNZd GMi9k]["oipMui73'1\I잱L|Li[49X=S@cJp$ؽ4Pv2 su7u/!+HzNLORmP؏һlX65YB9 akr !kbk!~pb7;x~WH,a?؛rd{]BL֘*"`?T <w k٣E)6gTo,9:~(R#؏&w"Xh(iN{[cv/WX-)LkT~kӶ9ZI_U{ɖړjuwPS7ee.Tn'Tj j"V5&쇬vr/s'o Zl oRM*b8IIeդjqM#[B9Uh592@vȚ"vv |[Y|P`]콦Cm $ DB@͎;P<$ QVf6Qe mlk5ܒOn2;k嬭+5 0.Vש+/ںyZ#V$kLX;$T+2M{n0.*|/¸/dM 9v̝5bki]q5d\R"V5)Гk¸57C/2I{޷VA T6Ex _hʦZ\y7EMݲlW k7Պ9uiK"Y6:Xj%%O)b DeOb]ZjM ұ5 [bTY+#d-?&72~ Zn}}a āx}j5Mwg&#kXN l5 y[}[٧pc>iTju2˦=7"]*[ZU}ʦZ\6DdM .YC4ebT!nNvӯDu D$ZN 7=ڷ:/ܰ DhP΁Z ;ļ~#s'jEFWPn z٫X`t}"ڱ0;xNuYkZo Le3DʆL2hTˆAlk"@Gȶ-5CeEc^&^Κj9k1IgM;2ְ֠?H ќOIZV W{7r]}7]Nf#~hEqo݈P7r7ue%x"<Ϻ v ZX~x7}8|bXq&$+b_i_i'Ղ;]~RzN6Iqӝ.?) 4姥NG+wK}|tΟyOZk^@>/u̔w}[S'? |k!?7J\s/~&Җ,!f޻1 mo&!IeZVxodh{BD(Ǯ >(Ǿc#7(M ~꽪]֟ja;.O"vӘ?IwQNSU_0/9^MU_}5u=s+gڿq Yҵ^{tOi1gA{9>f|6csZoӤ|Ǵ 9giDy10*f.|H\O! PYVi X:kΉxcbWbω1GlUbvfe}Z˳AխzV K_&;&;xQW\^Z[|7`3rlT곫eA3]Q> szݞJ>xzݞkОS9'mSca(H 4Ś?}N&(Fާuu:: q.: fr:㺘䭱\zIWQ#zx# ׌Dܩ_eBb+(aLKaXN}J1XCMܘ^N[W| T0ƱӇFj(EiV\ŧ!nV8yp y9[DogMĹw blUֈGHPΚs9:22Ow=%k`| }c9F7OˇpSfJ6cɗvJq-wn\WVwv%CÇGZ*a4ywg<=F m4 L'Jf_Ӻ5:DښˎۇNEYkS"cNUVpM}Ԟ~mf9cxnlf}n!s+_޽uJ7+7厲Hnrζ]%69ۜ1QX1Qc,c?i(5 I&UkΫayNlz=Q|Džf5j+TPL6zwmǙMĚgڞ肏;Msgrw^ĚǢ(k>s"ztܞ`Uw9O{&.#9hUiJzNn'Mϑ޸v8rIop*v۟ms.GMu$b|Iă&*a' cz_)T79&K(IY!쁒Iˈg&U&|LZ?ߘk˟Yakv{ɦc WS-kPўdDMVņ\>&6} oqND}H]}Do=;ߞVϚ~<.6 A~߉bg;0!Q ΉX3.Ú @ M_m죦6Qeg.76?!,1[]?֐FogMm&:Dx1D1zkRDe眈5ƶn :1I{qw>l3o/  Mm&׭\nos('1]c"h0̃={G(pNĜêY[_wV~pRD`]n=Qn |:7`endstream endobj 215 0 obj << /Filter /FlateDecode /Length 371 >> stream xURn +84hnJmRni&geBl?H’DBHRVhk\T\bLcP,^O<+.d*d;"DI-vܒb6Κ2nOtsִW SANόgz[Y: Ѿ:D`plCQ.(afT6|{p ƭ5tYTo0.pڄf  uA38n9ݛ[H|Х+vC:بv!o@;TDGY8ZK=CoAQy:t׿IBY5gЭyqBMxfB*9%/e endstream endobj 216 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 217 0 obj << /BBox [ 0 0 288 576 ] /FormType 1 /PTEX.FileName (./hexagon_binning-003.pdf) /PTEX.InfoDict 61 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 64 0 R >> /ExtGState << >> /Font << /F1 62 0 R /F2 63 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 2027 /Filter /FlateDecode >> stream xZM5ϯ8g@]P4A {U2~nm%,OOK]KWrXºߗ?O~a-û?OoOirmX]YKu|yjp<}}nnftHޅ߂+ )- ܚ\$$~Wbq[ gEpf8gpVxI.%7+/m P𲹼ܞ]vpT'pTJYʙ᠜ʙEx{;g޽wo8yW_SXk>B|[_yO h{gS8C ]acţe|*ǖ_Gۤƾ}=]aó nUb?nlwl;{}]a[Ӧ%vW7JE"m, cyߒm^U '-B?&D42j4W2fŵ%W sJqQZP8_Ra@v^j ZܺK)4gy(1xxH=&"id@i.TOp‚2E(E PaeX*BiC~XoWc,Ah>Rs J (TO‚id@i.POr’2E(ŅI@aeX*B Buŭ?]=}=-<+<++`3*`++`3 Ŋ&p'CgwpV4 gpV8 gCs1á±5áA5Y᨜Y\&\pT'pTF ڇ1{.þkeC(c0=czVcmئQ31w)))gNt'k`h(hCNYѠYѰfwhZiV8.5#֚ߧlW}cD)64}bD)64ڻ ٬p pT0pT'pTFٹ^GTDXV *fd)M^~6Ib7/6b/;Y:I띬>Gj6D*]$ E; 6yg2Dj/oTmR(,#|Fyia/G%s'ہK6rv(/s@y8lel JVU D`*V( !Ыmǁm3P.R_=bbY04x@,r HhKr e !뱝}i sҦH5> stream xMNM 0 W5ZS 'ua:7#I2E2 cbqM+fϙ~)2 JBNsduw7EڝˡE >B5av|j*Qendstream endobj 219 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 220 0 obj << /BBox [ 0 0 432 288 ] /FormType 1 /PTEX.FileName (./hexagon_binning-hbox.pdf) /PTEX.InfoDict 68 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 70 0 R >> /ExtGState << >> /Font << /F2 69 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 21 /Filter /FlateDecode >> stream x3TR0TR( a.~Yendstream endobj 221 0 obj << /Filter /FlateDecode /Length 333 >> stream xMKo0 |@ȎVmM6@˫RvT2-%h48ۂ+ɤY> 2eOsߒJt%X%]ɜtVYVu -r4U ;݊Ty_? 97x64h{ԧ>܆8 t-rhNxsw6!w%pc}YR fD+^W3x\e3/m4Pnq0~$փ0w/|$GykeYY P2y+endstream endobj 222 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 223 0 obj << /BBox [ 0 0 432 288 ] /FormType 1 /PTEX.FileName (./hexagon_binning-hdiff.pdf) /PTEX.InfoDict 74 0 R /PTEX.PageNumber 1 /Resources << /ColorSpace << /sRGB 177 0 R >> /ExtGState << >> /Font << /F2 176 0 R >> /ProcSet [ /PDF /Text ] >> /Subtype /Form /Type /XObject /Length 21 /Filter /FlateDecode >> stream x3TR0TR( a.~Yendstream endobj 224 0 obj << /Filter /FlateDecode /Length 601 >> stream xV_o0ϧ ^l^(6"SCe6%mO>IC 蔳;*NR*H&=U R(1Pr/O@ ~lh%+6D2i="tāZq0Cʚ:L"2FS)kx!k/|6@+9tsLkx3ՉѼQxV H}4o_u:!?> stream xڍwP-=w|CNp %X!H[~sνUWS5{uFSCb R89x8E2<nn>Nnn^t]0A!" ! 69 q9x<"<"^nn@sT :, ?ldvAV@g:nrzht@ `]D<<<8N0NVA0d MtMkЁ=P9CܜAPcu /_vp+ѿ N.@g/-TP{@g@# t?WGYA.p' #4mw890CAV}{gN6`gk4\n e1&lAp nnnA!]@yۀ}`@wuoyx`+8d vFwG3`O1dagG𥎖ߔ唑x|8^8x_pxx~_&WFeg@/ߛlXYA ߄vw~o>yTC @ Zh>e8Q!ζj#YkVv-?SxLviB`/75gR= (,)l=ǹPO/><"ym3x$@OT ?7xGv+7(QyX@ +i7-W[ [,>s/n7(I,_@/;q7ϥ}kQBo}ǶgG{Fk)(8t}]}4"0为 ak\yt)zt/ ڮPŸ+֋2 *dȵ̜"}De?ę<Edžwh7z{TNFOfDJpGf7YdƧSԊL`7]Sd7EjmVPG} #u OCMB9]y&8R'њKU^o;Ra' qLg\%1E5$eyC:~|_.9؇~;,tax hZj&ko\WIxN`v4 j_\M̟ =C (lj>Cn^>rl rզ S~NG6R T:*d]ʫUߦqjOTOԮ^Qhƈ+KO<߿/31+}Vox-o.i3gfiTaT!=A-Rl-I?Le s|ц%cyCEЍZwHlrȂn9?M s95LOJf" Ww9=ZU6vW g~kfw >Ď&Sr!}+cq+9@,utYJCܤg!L}Ph!tzQڨ2قu|0Kjj$K/3sg:F̻t1k [6.Å'-BMugT`gaU YۛyR͕v2 j Nz[v je@-5>UyO}V<㎨T=Q2,2g?oE__Jct})#cqwC© 4 SUHn[5r濥gWί2Hj4)tZGx7l6_*T8p 0 8Gp$EsFOKGGuCaﭸrvGJبbd9G1ty߲v'B\D¦Gb 1pp! u1,*'VK Gfe[oE2qSAnƵZCz4Lca~^V 4Dc%B^#D^>}V{/c.PBkhʾ0Q%1b;*vGǨrёdh~"^[] _$:==[?V˿;ney$oRqb_˷{ȈɀD9'ZOBLA"u'PO'BA8RӲ(eÞh#FJ,2Ń״$˯{jɹj.Fpd<u7 )ŏ%0sc;aUL |55Z;(ksWQ k@w^Cklm޵+; Nkmn_DW}Lyj6#='bb>bz6bW&BVvF#b=abn4T!VۈlvB4qٺrSesE/Z+?tIƓ\%pڴՊ^?JENqij<3McV= _7\eOݖvōЩym,WN]53g*Kuyx%g;){TH*Sr?3*MD,/?]@,3}YN80JJ9No C^zd{RM_  oa~_gU?r1 OkڈH`߸ś! QXPc?֬#IIƆWAMCTp4´pKf oq̘ac 79ѠڪnCp%cGhOn;ajtJV$kf4&Cτ*]%r4F SrV[byԣJ{X|Ja!E*;h ^'}z`VBȜB]'jfPNA'S8W5cJl6&~U?|L#ui\DmjJT"Pa>m =QCpWE`ִj7()FEЯ-@LAVlh?W'[4tM=-ӶmȆdv窘 WaBaQ@]Fx ę&}EU&rTFxd-^=b~nL^ODi[s$tmG<eZU>a/jZ[>aP"'U jttj:N?R( FD`&ʓzj˕xU8/X%Zu~D#[(44CRFbĴ_,MaXP7?c VLS*M;ީSvul`-U{^xcq $cыrcY;Ql'j61#L)U7fQ Fjܧ_W{(tG ">IjļԸW˶O$.G!`3D8I=)UtIۘΧqoS#T t8mЎT8:0$r'jߜ(X@~ @G i8 )HSKW}DSViV:'u9!SW5l6PSyŸ'):uRPݙ+媹j,K"g׏D3$%*_uqv~}俚nQm6<)b}lͼ+ ܐn컧?Bgwfqg<{J5?D% ,"c )6s)EHl]Ccݸ {8^Ν|Gֈy١ݿdyTS®N/@WkíPDCoQ>P&~ZTMc)ÔBwLBdrI` tlC(:@#iHR<C#?#IrMvD MT3'['իm ~jܨ5`U2%}Y"[!yQ) f":y>yfT[}ߪK+{BO+1:Y|`ASt(GV(TNʍ{ T֝wG\VUY=x]69FSpB}CuN7LGBk"zPT?7 ğ4ɹ*RCNZ\;+DXrD9UF„+ܧm7VT̳vPw&ustZ@Yc+@nuݮUȖ3O/+سsX&eܥu?b*'hM_LXeÕכ'?PY\fF2 `y; YJ]_cAmC1J7iuzWWri؍b]٢KqpG5i&t;Gm›W:og]F ~Aϫt6BCsvKeĩ0GP9K(~K MLo5&4NWxw,Ư< !&P،x}4-_kEAmHպW(VѶY ҰP:W\w@k!4rH>[Ә}C_㪲#c=RHღs>V#&T~,a*V$o !L۪ K. Xȋ/>N Tc^%H Bi%zM(I~6Wey2Kx*3I!IDh##t̾n ^aR_iu"i=dV\2WDaJaLHܥg%Y43K)t)SKJfۓi5&۠N ذE0/q8% -iSН'`l&Mbغ'pس蝸 }Ґ~,B1sHd`=U1U3_} 9ՍPW0%?}{SWEMZ^il~6쯗_'=B)ԗo-,x*K?0,~ȘʷLwNjO~{%tTaKuD@llR,ҽ*/MQݣ8u 5b{~NpX ŤYӡd{UO7~o&z+9JRL"l,d{ 8_|OkO xrr1pFN.p`DLFSifjQC1 "Z4H(JTLJN2?_Lؽ"KZn@.R,m RO7:+$G cm hÞf3޻)no䓸(R1œgۙ+ض0H-ɧ{Vh M,x[H mM?"#%V[`(*CAK;5ц\Oj,WgA]7\HV8!(1-\SSd?Ms;TdTE-0kȸ:XuDڌ1>hV&=..ֺMLam;:BbCv9rBt;yg>@:`Rm%gWB6 m;S"~6NcѪG+@Aɑ^գ|()ujEwіGkosmZ+E/ѡCE{O:K{𚄘i\Hgg1?[θ*ՍdLK* @gL*SO>r8RD<5fp }FUR|O1)Y@ߧU)iJd>G̥|]P[cN07 ͝\&2~rBXJs'7WR 13t) MbGl /i 7dNxye8Lm (<GYfN>f9ړSWCendstream endobj 226 0 obj << /Filter /FlateDecode /Length1 2037 /Length2 13546 /Length3 0 /Length 14780 >> stream xڍP\ CpwиwnAmqw'{p HsޫckεLYI(eofbcf+iXY9YYԭ T@'g+{;X;o2 c𛡂@`qYYych0v2(0dΈTNVz|M+ sv½JP02;OӔ'n2vG9ysgfF>GJ]LH}xx͒,YH 櫍$Qy;9m^OAŜS uC{w;+.fz k>~; H v:l1L*@2c㢔¶0[e馹pfbf s2! j*glٕZ}̓{eqWjI ~7 ;T)~IA jյ,kfHxq}DmpvOWKYVs^B8{fQTd_z[aQk15ׅ!vFyo4NiN^ŲzmT5@i$6ų  ѷ UKO:98C#`'x6Gt^]N Pz_ߜ:ͬC Y?$ H7Byb)6J HLP2hAuV,czhm7'V",9ohU OyFé'0_N/}ֶ~{or-ISB6&}Qk].š%Wi#N|}q&5gQLa8F M)xi3` 1~1Ke6 fY Me늳Ͱ:fpO.q5,[y>%<;aOY8(|5QAt[*h)gM;xGKXzgƵ,PYɅE'x&l{ٛʞVtE|lM5Ok I">f&!b16Ǧ/9_}ﯫ"1;يXd_7|bQU~rhzzUb@˧5-{(<d =v+6%"Z8.g(q֙/3(9h}\)zUu),ķҺI=r*b%Y}簒 lC+ysGI'2ʢu 3H92h~IZ Ϝ,BQpK򣛺+9g#V|{Q E PD^]dD-hI; taXo]?-R> +l9v*n_S*`spWM.SAqX|+v6VIb_'ؒKT@p'sMBx~>Yt%U5Y@uLi}/E}INO2{)qlj4[Y\#;/܃^&JZ͸oҶ!USWP~UD1+=ϘR״ߔѦ,³xׯb$udOҦ3O) =<9r= HPGB7?x(./㊼\?ѽ`%&_;LL&. hq"jCڧX&c=]Ũлy4yLm[Rw=n Jqβi*DMA^p[=W55󱏗h~=TbAї_)Ww .N1{u-V>-^1C#[OrI%sڔMYf3ni=&Ee[܄vi>VS忥`+>Ŝ|÷p&ZpžH?p.XVX[eo]2WmuO8?+^ }GpeȫD?iK R9:LfVBDMl ٍT_}z{ ӳ򡗂?+dCD|<8?stR fy`d3o bg@sk86L3Գdmӏ%'c d390yR~qS ߧz|FKs)Ƌ2)hcIܖmܠ|T/dDy$C7%RBx+i%~rSÜU/ֲ*Ho,5&$ڧ&q`8,=rLIL e wQMCUd{ѼųY뻁Pt*mL}(}݂m:"1{GƆWHtrHH>aZtǼfy,FWFi X&k~ߧ>jowWZl\h.2џkS= N҂c'o5቉yg(Atqb>%כHik7a "b533&A:e)m8Ye@u48ŷem]5!L0 XƩ}uf.|1jvQk>&a4yXAtzij x@/-ފ.PYZ6ʑ+a3j)F?LhU(Qy\͵bbݧ%: ()P^.*jZ\5~h a,B}1őq6 m@ hT/tTv-ZKRYJ, ~c؋GuId B(Kr'3݃* +RHr!!) J5]tV/툗TLd5FԵyY CLp5o-y.>(pΜ#xO6Z:^g*_R%_vvL "yTV$]pͩx4]]wjNV ;wm\hz߫`HØzmUrujb%b.dQgL6i94r[5BVg>%%]aPҗfȸt곾rP8ʬ0aeq}i|y\ _`zô-Wʩb`]a6,\9y>㞒nVz.S$)^1|=(jK]z\6\Ǡ)P؆о+tokǸm`'i.lT*MR]ݤZa N15[=`HbOQ_'fEƦK@yt UŤ`T) t׮ >h2#C$"zI[ 2)9= HѐE>u 2 O guw۵ʣSAσ#yhsz!H׺^^1W[g&д"4OSYvři-Vjy^BD+f0fVG@B-OGջ}0 , 9_l(ϐ[<E,-,-NϳXC"4!)K}T %~:xEH4Qp"Ix[RLMI"8$ /0d[6CE}2D$-;ZH?aai.u2KƼ¯T Z`Ĺ:,EĢa ::};gD&X 8ncRu6ypueH6ܠ.> ɪ,&92fVw8tKyacAsv nYHc(wm?):'fW8?/8 -ZZQk8^;"ҚD,G@1XG6aZ*7Q!AĖJO2}6W+oxuiuDN:sg% u-T,!.G 5-¹Vz~?,jMAzJמ=+=̻^ׄ->qK!>%5>kƾmז: 9jav@*XϰVe RqOP/{T[*nAQ^Ԓ|6D2[es}3kʭl܋=mH kg6L~NOS#֟tK* ^ Zp,&ޙzq*@_@H/c7zh!GA}7Ԣ-{e@'%kCVkDm#GRRMlUTÝ>\wm(jP~m`xSfr*1->CUrw:1tY! BHQWx8a% j|Չ²mfdЮ{ IW`c=mX◊)އY{= ~S-f7M TjcLV=CyGikyRnr[;v}$ʹk XD mR+0rPSԶ @1d{%EbV> xSa.MxCtOjUoTr(C9_.CpՔN8qTWk 6I)RCY2UcB];pe-# x$f7_ '4q ,j/,BOz(6 \/3.ԡJi$gtUv)y%HVK/O Ρa?l|#zniIbPE'1<.skQº'}k`o4n V@hK|A E 4rc~p^&'*LN\-firty(oHi Hc ^"GMcɆ ɤ6OJf" 2TTEZq*@׮.4gc)~ ]޼ӂ 琸&J i+I(QʎY䶖8$ `hc^Se:V ;@G48x(!,1 b^ ~"K>gfӛc;Vb6Y0,jF&Y҃_ʆ4?أ)8|r4]Opb*Ӣ3DEg<0՟]>צFXjN5ǃěu'_;{AT{ d4[\A&8 <*\:4pz41 cu2ދ9Ͳ£g<4 :{FS ŗ 썆Q[X_,(ݞQﴂHAELA4xɇuJjsv*݃X1*ANPy{FE%fdxF+KUvre/[5`>Ö}OS!h6wJ.䋫陯íL5ǔQ{tWrY'm%&WR%P$aYTa~K$V3T:Ů<0'M!tiϜwi ^IbxZQ ,:EW"%Bh()C:Lj= U Ts_HTV?_v$DLS+<!J?<+5n!9Bt}YjBxܑ tf|u`&1fT/9 ^Xv_ n G ct )CP1P D5|_qPx~O~PnuHQ%ʠ' 3Ъ#k&' r&L4]ܡ O=3fPz ⍛nR97խԗ*Grsh1|j^zK-1Y3|l'|}u 7S;d5L(lN濞Kr|f*ZEcKLȢ^+- "IVɖSk&DڕaNpÉ!i)fiG_a_{=|Hb"#6A&gJƢ)[20aƦ%tFqѣ.؁[0E_/o_wFHA2"[:ga%3i pbZ# rFB}RxUJ$L3~EZ{g; &NmԳ%|%A5|#ECכ{rę91 M/ fs-;!= 8g6/*L,֬N7CΈז 8j 0{بy:g#Ro: )HGw2sbr `fY 4Xĝfo{wNHˤ[ [=]Mb=v1(rOezEyP닧ˠ7'C]Mټ&Z%Q{K_ݕ!w^+-<-F r[R.|`;}l8 IYa t["&1T(JuQiK)wWn[c%,,(7:I\)p,ILd<7BHN>ʚLH*=4dY%T9ܧ#|@MӲ„\*%#fV6ݹ|]L<@pDvA3vM7́[b|5b۹XZ ?k9YR`qcb类MN]$"cmQbڰ]BQ{;pJV#Z\=  yy7 ?x,s?7<0-@n+R/wd«"}GoiS$,O-QW8`6Zr'o.3J斱JoN0mj4cr82{`V=N}/>xSFHaQa ֺ&T;g8&-Њ{+ Xr镞+hЃ;bhy?y]{-_wX f@}n84YT zjD0ϭL5*wl tԖS[=UH(Ni11 l~AU~:rAG[=vc-奔fgq^5J`%*CHAmqMRoj xzfFNVqKrEƽ3!6x} #Ů@>]k8]>1p<U #XO*b܄X SUԒ7XN2;n ȫ8_673dOS/|g@Kojm#+MyXv\MOO =2D7F}V{r~zt1V+LԢgѬ -w]c9;\Z*9=+-A4^y}D+; HUOC9kD9yzWƱ-L_E<ĤR нʼ8dY'XI>h8}b 8321=GZ)o O@Z}*7--L%fe"G/d?^FMG:[&A ˣ I5R݃I ;q\Ppك{ +ǁ"u)++u fc`G{NPhyZy *a#ջh>g׫!.'}LiHBZȶڥa*~ixk')NH[fplzۏ ""(g)վͫX=cn'Փ^XM=hU5; . ňN89јoMg (x:=w`vˠ}}RfGGT 1 Ny.5*rh=14X|tc$ٚ|$qXGCWM vK$Z5,&W3d.!_#`X/H,d/s0cszAQ;"NԆ˳$o嚴 9llck,W unDbDWqD*0^Vm0'|G;~V~}F=fqMkQDDa ^ ,x;3J9"$GN#I?=$[߅䞞84 k{r>f_&j6H W׻a '+=#ZAOŚFh9]cX-~ J=J'C(1< #ļJd@:N42(u~G~ _ݑ N"bTV9}ug m3{aPTX0 uvK+xwگqryJ4Q*>" ouBs$8z.>e7X/JTrs:HP/`#r{ PQH@Մuوj/E;3Y< `R*_MU69j58# [vĺ<"!WkqrK&isc?%Qwp_g=܇b1kZ _ zIxХ ZȚaR}rA[[ӑhT9!i7y ٗ]ٮ8s-jkth g6};8uN'MðLlҚBdȢQ~O."=ǖvuqky}MШz%swHҾIY_ڍ}FVgaRnFyյ٥r*.ܭ2l+0SՁ`L-iC6mt}/Z8QQԅ CGV5L"ߎZfke^Q}x4ju}"P]5 *%bP]b)3}Ў优eQ>"y=מQ-aݥIB^Ɯ _˩PN[l\RV8a݌3~V}?)(h`4cY'SMyA TL6.Q?eꭰ"C a(Tl20Pm8\Smx߫c֤|dm y3LO8r{YGp'!ء-U.wXXS#MF-njٱ6L}$[f&9yh4<6LXIe2]RΤ%TPlt";GH L*7,J"Q2!8YB0eyGpl7/ɾj]Uz7O:W]cCBSӎ|(z=}%%6y3S2&c*B 3U\|b=[H֔q%:Ov[f~{],$N:EE-߼Jhjo<1߃Ek*u0ΤO͜%{\L% ]YsPM5?}'@tC>ss>P+z "#2Hx0xN4g֤h}{j8sZ+O7_"J0H AayE2ݶ+7:+(`q6wp2Ar˥j`1wG6T![~j& ~yTy!5vѨ2͟\eԻ߀"裈FZ"g)^^h~r9lGzhz?+8pTָ\=19\-Pн+CݦPDu~x&)'^];-a5p=d˒xy _w7Ѩ/C{EL٤뾧!$L'(Pζ!89ٿ% ZK:6tr1 b9!IIT/v'25=> 殼[y栬(,j,黼If]S]/֗%:2f9U3DAᜉ=9cz7"Վ -dtb0f%() *xqpdΓüFObFaG,d=Bp zGY%$,t _C2tT7R^>E49 kg7Go!vހ1ݏR6%NqPl{99+Z"E@`-r=>HW YVH36NU{1UR#Eyܵa//q$:}ARl/I5x ?a1vy!8r W3ڎi, 2eF\/ Ʌv~iK!R {(#k>>oBW>]2Ȓ%rR-_:-kROP~*|cN4zTQ*qPB! z_KS9]I$vaߣ%-U)e؇3!>T|*yT 4ETHQ+"QDTs>ӂ/wze%߄%(Vś+ą|/* Mevڕ `A4pv˾gT3L&IeXdϻ?"#endstream endobj 227 0 obj << /Filter /FlateDecode /Length1 1585 /Length2 8505 /Length3 0 /Length 9550 >> stream xڍT6-CJ3tw4H0PC ] () J*Ht795k<{}{=CGZUj:X9؀) b9 0;rt:  R` .*P +'8@ ΂iP:]餠+k<ߏsF {3P ;&yWakQݝ duedC` l]2@d46t:5O&r;9`v4j`?4`?3jr8X,!v`29X6ٹ@ 7d7 :\̝!06YB jov>4l'_õu;x,!˰pudv8Ya ??{[NC[ X?. 70 O#t0[A-;C<@88ߟ :ykLj%h0U?JIIp|OkGDK(wUw%nQ᯽aw U(`ÿ7_[GO$jgOdNhW|9Tq_S]V/l@?Y5fn'<}w~g _DUs8C-~$'/ DSx{y;wkXBNߢ?]_`W Av\#eaG }› `]8p~6?5ޡ?  BͅԾmxκ9.rv:^d 4YMΚW(;!klӥ*t{ޓRvۊD+2Yf|I QhbVt8>j')vvWf) iZ̆6yΉ_GFfP+ wޠ'W /D*mӆdɤU,`-q6#߳([fLU=83bH6M!s\ Ls+܊F4$xӗ]X#U QX媔`e-JCƾo]Ge(b f,]_AZKi]N4v- o[𸸰 i ?_z{q?uvJ;UE9G{-dq7Or_X5RVx|Ë (s>vE!fk~AQT5<  ݭ40v~1Xs!.+ޡ D9TEn{ ؽWl w'sQjuJ҆8/+X Bv(Ʃ"l~fsY$=44|4{ҎKglAl$,^UDŽ akcJϔ Ռ]vgbmq5ڂ  6|Kp78~q<17g_s%}U!:bMրHK&Cc8ҏcchhǿ᥷X{-OshH d]PU3#Ȳ~FHcǴ0+3*|/,["eQӠ&Gm˸.}UHeKү)Zf%:s{Z#tu Q҅4/9:E{iu[> ];ȫPܣFXyr{uذ,*H0Q}z1*F n9Bg?Eh&'!&;h}ۚ+n 8u]ߚHbGԘK|/Rifܾ܊K׍-:ÞW^A +w⧷5h$~3cw`s ~]BxEA %DV(9"A:DP22AG?tBgQ#Stq2ڀlu7\M/&9uHxLU#`!UB9!KG#mn?zj| ϿG4r05G},x:^ }W)xhSM4{ ohV2!|P=aIoWxM^?z 7`C6:ӌVZ] &T7cSܟmJr]1&|nF)j2LcM-BXڔoͶ? ]I!we  ~ܼy/6Nyjr^ oR Uw+zin p*>Ɩ=dMwee}7r ƀc6D2ӶTz:S/3*avZd`_.! Y.q#J@QKEJd$mP6vD '_dhwhgWBDfᴒG^[$/^Dw,6~'kMaGafGg  F̔/mA!yD^ ci5, ,IDUO>T&:}lTc@2d}CMB؇.H~\_Lٗ]tJDݽ@큏W8Ko,&DʯF^JUni\@fE\obnp1}˖ߎ=9͡j\l~ ݙWN2GPOQTmlMfNLdMpUh@g9$R[„pѶLE#N,lVbz`ӎ!h]IX[%ґ;mn2{I&wZ~ȴ YΧDT8ncRPzONQA8 ֪IQU <[O=o=+ ֚Uk2lx2w{ptpTy@S]Q=s! ]X`׿hfۊG4An˜&l+ *6,*P%?*@9 rcS!%h!v~6d!㗉.X}s1klKHg2X/K:R6+QpvW&i%?b(#G),It]F 2grÕhbpњPCĝ\°s,Y{ϊg֒3b[z~צDQi(dR$j[֩n|TZ 0RELwqqSD{~{ YB~O'J;/S7HɽHT[ۿ#Pzvȋ-|5=dji#ȎM]\{:[ޗ%VGv7_G:"TtB!K"ŏ9M.6!膽0ygG#7ҫ4o3\8e{^6T0k`la8C Ѽjgf7\P N=Y{KE\(eMH-Ö^*]0@`8kσ^Q9~2ﻌU-4~kqrl8{jWome ڿbЂI5~TߺX&}700om-#솙EHU:ч)fN!;wh v%:[p2]Ye9#5i͇]K3ۧy sF*$pp /VL̨%-~)Bv^j#HE4j~Ռt8F.qv7EQ`2&'c=M-<8PHR49{]\ * j(J5ҀaxuU"e e Ii-vlT5uL-Wp+^d+!ygB]8pLdK&^5xŹX0\^=zlnZзY;' *^..fr\ M]Sseû%F-Yʙ=Qe42,ksT9eO_IP=uE5_o&po{Ǿtg" 9G6 ~1^x&[^Zs̀҈vIZEvїm[i绒V0M?jtN`Hv9>Fbn_yND$=F wHh<l֥4$saD"bbA'dakOY!aܯ!|N˚Ѧε؝SVImؕy3@~.?_Kr+6.nМh8L^%S,'k(b0>"|J˒4-&-0rdTy_tvP#u')Cv[Ar3 !]ܧ&WĔt%E0o;B)~*lv}=8BH+Y?.#}h-mguԆiQ ޔ4#`s5t LrD 0u$nM\dZZ.bGmqJ<&["̩Ujc8,"&=e(mqja6b!bonJ ēĞ{J'u=}oB`zLqgS0]胀@>AV6l-Gja q-O OCSq R  1"&#/&n.j-ZO~Zܦ[:m:yjL Qz`f#B[re>}^xb3PkɃ{ N=I;Wr&JgLTQzf4 JW,B r;]0*#&FZ~ܪ=mVB&`V+"=B=Cz||K7]\!{4W2f9kW~,P?M`]r/?FځfkŻ=yd 61fLD">,擉@]QugaVw!ɤ|J&8YTҾu7x^Pⅲ:r$\Ļ> OK[Ā3RA|N`"ab GGXmd5LKW4lM̓#'I^3I^!*pz^7xl"8T9U׬.NaZAʉuE aJ2f 5U ^Y!_F[bܘ0F7mFb1%}sN=c^&e'^R,h^I!\@i'vO7j13ߢMs[o(. b4=>Ըw"qrqI B*h89*g YR1]neDNA=|etf'zF>W$#;T{+ne7*^)hІ<{f΅&>Oql=[XΗ[lU+ڡD,ECcD|F"^TH6QN#g qy0r;bTog"cCv!q53RV1]7*$cnC?Nm?HT ؍ Nh0?u냦H[.>xmșdhThFB6էté>ܯNOь'550 mD7AiMc&j & ΥT۟Ig ݩSJG]+FfZx0%ӥZΕl}l#K9ѯ/^RI }EL+I[y6A=܃%Gӛn I:;o(V51'xA{[JZd.mmDBD80y/}WJS},-^PAKJ $ѢCIlJ)H 4VI3-:g?E aq_iZ)Fύf}p`a1hP`hxS1Q1izJ kmСЌBwIȂdLAxCOp~N qۨT"LZ:k`ec/l4STalA^3/R :qKNH["W~eov|dsW6X*]UKE)<IɐtcpކIjc2dpxX\s/N_,||hwQѨAzF_W(\PU2OGɹIU 08A$^0ث6 E*FE0MCv6 [VLDy2A:h?p(>y,%TwMI)]nN-w&ǏE~;hj2cJ-a伌 ma&I~:w<|SJ"N-Xe7BMvK^80A:SD6}F.Ew(1]QtOf95l/ CYU=dU(Rֹˮх\wI[9wkȶ9Kg lkʯ_DB~yyvvMЏ٘pF5P*o|?T"(n S+{j)#;ŎSGï)Jbplt`\&4MC4f_glltkœ,UrwS!d|}1:ژq4k[${>﯁7\|*q.v3D=Í#Bn _=Ӎ]Dm~;C,pD չM ۀ!|S_9']s@eRt-1uypŚ봢 j&{*Xi@+Yۉ6IòyE$F5Tnw|rrwpNbʞDDwi[8J}|uVbO .>Z<4 [ 4 5x::ǔշAFX9<@>\`>`lxNsߴJdĞ_yk߇1E95d-n/;WDoT: Y=Ԫ;giC"{@{$gI4Ւg{T)gbܛFvls$^A1˫ZȊwVjz dU?%^ zp呻X]|Q1G6h&2 u\IZB}2Z[Cb?+h:2| OS.kZvǺ'eOP>눮 l+Glɤ)vRR\8Uղ0,&>B(5&fe"mAh-Űz.N j`r~`~* &u rϫʰ:m5 ߉`-ߞTnv;}.;$DJqٖܦ:J~D!Ix/v*,t[Xe8DzpN?"G+kZTVıAzhQPI,e~vwƱ.,gD6x?Lz4twۅjޡ=Dua ̘PfuHgFu#Id*e#ULC*56;?qFIIQ3dlTG!,R:﩯B<)#e:/9 YoLݗo4{tF(,Jduߦ%4X'; řPT40k[LtarM gYH6a,`FthIƉPCi$DePJ&]YWz4!V,CLToL5VߛԈɁYkl.;{>AR"kTՏkc+;Z)bSф_TkG 4|.S^@endstream endobj 228 0 obj << /Filter /FlateDecode /Length1 1420 /Length2 6503 /Length3 0 /Length 7471 >> stream xڍtTk.)-H ݡ CC4t7HHHI ") ){9kfw;zzteVP% 55U@ ?ȇlC:Br1A]`Jw(Dj?$$|@߉W1f !P7B 2̀@uQRrwtf?`'_ (*#QDTc)kBaNUEQۢ(  ܔ`^PkbHu# A~}qPU@P8*n PD^/ٿPCֿ'(P@Y_JP|HT `pfqx~[(u5on&( F@CkCZϪei"=]WOJEw&~8/J~|c`M!]A)w𩸟Y*p\~:!9ے/r"WTT;SM^ `K4=l>gns\؟V̲ᥛ&xS% [%R&gE뾜貾b7qo!x %ˀO̡8cG6q=:II¨Ua#Y@QX_of0^2%ٸZ}hzf(L_T.Fs֐/@rѺz,R K Mn>\/ܻjٴi c^[0]=>g9yKF͂q>A{vkȇ{I?X;122!>|֌]+q_)euLl7HcVfxQ6bq->tӫ!Y T2̈cmGhʢ|їd?͟CUф =h8 -/K%ή~8<, M%&Ê!MR>80.gz_ҼXE[H@Ri+ 'q%Mi[˝=|]^p"my-!}j΄nVUɤghsdxάJ&Nc[Q] k a'%YOsAQ(k^fYKhRu,C'o[[2$^bja֛ g i'P ȕw23 :;="h] g2&߾>5 0~b4:Bz|qW[܆Ogį̰,R0e}_61u=?;Ș~$5w}{U~ѣ}1}Ob-w)ag%U6E1Ns'BZRPvaʓD6^ ZJq6/o#?ЄEI&6FQ hk~O;4˳$-}er_@30R땶uJ Hi z?G͜gu^D_1 {È4cB>)#rg$**F,eݣ9UIzZwf2)6U9; RޝeNDsXcKS_ש)CAtmۮ7 Œp4G͖VtܤGji%Zv_?XH97}DGO@vLTIpFvrᢖg5e{Ee: He aJ34,2pQmQ#B |zF?LH.Dj/yئ P*ud x}6$s%]z)`Iݦ>P7}nDt<].Oг98BپJ +uFv_.XGrPyxR@(_q! ԙ5<{ZIڋz(ѳ&h{r\qw2'u kCC ̶PZ(Y8y( P[ xC<pKkL="wE N2d8x]]2JL(D5_#d-=)E(HL}s c&|rʁC\J #:/nh,*?bc94]$#'-7\ GWC;c=/ '8=TNcn*ߴUԌ^EqMp6 "wf~"@Pq}`wdCxWc3ǻZzP~]aWγ^ʻ{e18Ҭ8Ѷ>䎵ʼng߹ެь15n}+Tlj~oGItK S57(_WSlMNxǵV͑^a R5!R TmnưpBs`۳Ht*t~/N,1_e]6xV8=i5l&j;54MeteaEm3ֺLL#έIUP-I={Y3JRk%g{(8/II_kg|&.#ͪ7/hWl'9{zPGA¥yPo 0d i2*Zڗa:u]`iO]ѳ<'ze֨c`l"H@߼|OfTb3{lZ7MN(C٬4WxʊbëO:лWNԤX#RC^DS=TZsR0LnRi;|؟e9eu$Cnc7@.)ܷ{dW~pѺm|C#x bq`6܏۫0@8 ԑV ͚^l=q(R`$c慛8g}ǒ[K-,h7[Cm +JSi65"rM6s=ElhuUi1V2. :BWK{BtĔٰϫp-'--hǴ۾K" z\ge7Dz_,ru|zu֖\Lj!EOkc0*LOWsKdt qDs"ףr͡kJl|Zҳ6z*坐\՘*!Xv=uvˏLbn=XYPoBT>1{3ږmngiiouY <%w3QHf~uBcܶRk>]% M{{EIy ;>HczY;ԕfTfy, -'74)ߣVXy581ڦbTpvlOēSǯ&6Η.{?D\js/rX qfkGoBPOrEJ,_<[}Mח=_ΖTs8>ӆ|LO/le| J&|7:@'iEkL,X_b>Bє$wn0ەEy z1K[K;k'7wDUz\ Ϲ@)V} z+^0\4m7׈$&<$]G_i3 $?35ui Y݈M_7!ڀiJj1JV=̤_!-N2OQ_R1O!hBԽ]}fjQ ]D],϶S W> #WPGM/wa> 1lyvY[` }"Iw̠t {cŸHWqkbLr{eڃ&_ssom˱wS:k& G4ey}Űz1:zf&!WsD]{wtƇ3IjIx5S-'ep¬]E8x#5*wLjs*d)71iDxYv+N~<1ܑQU򞡼GZ]*ctHo4*|pJ^F|19}_V_m &XX)xcJ=w5i=&D|9>vGfZs-uDh_՗4 >PXoݱG7ɝ9JrQHT*G7"p5(@Dk|r1*X]u{LBxNlO\\?t\X+ږgtOl }ۖ/.P5:5h%Ħ{om;J,XFų]6,(CX=G@_meU ,0N,'r|g:>8wVIxu8T~C*Ŕnv\9<  _[d&ب fSj7睎HX,PG@V“^߰3fֈ$ߔ֯|\fNbh !R0m,Sd"sZhe~ 9zo.Q4&VS+i'+RegΞT$$*d׀!ߛܙ /i7[d̾۾G:ͰiqbMF -CEV'c37ݡ vڽtsmϞR]dDbyZƩ cRe!fcAWeBĨuG`J}MBߙ9mNN ؖjtg[#=iR4a/ {5 2>X.|gk^$wL:tYr VNfI)xPGB4%MSڕztlH̆-f"yGbi!bPgw3/]?` cTPiw>3&]ONt4K!b9[;U \Ęd:w\ٳ-;n 6.OGd !3yWy$>9I9 cil%(~NiWF:l(ȫև]|t{zթ$b:)Iyޗb.]9Jh,[y;p}~ Π*UhiS$nKz >aߑ[ɜbŚZKOϽ"zcz8(/#ă̖Ɛ~r|D1~0iD>*hR32l2,Ah$OjxL?K%t\7&C)=Ŏ#M\1Qo*/)u{1B@j-d55Ȏrac`K+!sE;'mG_@wU,㶟`]ooJwI;lpszq< K&)/LQ /a<(¿,WMГ[F"#0[n*" lv.dO.hendstream endobj 229 0 obj << /Filter /FlateDecode /Length1 2548 /Length2 21711 /Length3 0 /Length 23160 >> stream xڌp v56ƶMmVc5jиmv N{Ѿ9g2uyDQA(ng Sfa03123"PP#P@v8dFovrvik C;G^+ :!P{8-+ڄE;@219[m2YTL@@g Aolhdhh.@Cp9[N@GW)7a _( U̜݌75hbk t%H쁶2=߽07ܿldbbgcod5qYFgwgzoC#k'7#W#?ąFoMdMw.ٚm~' r݃_s70ٚ&abϤf rpJMGftp033s,o |fo$> 3?/'#W  d 0lD߆r0 齭$ N/ ۹ؙ K!T(ekfׂ'C vo PY}]ffmoA.l@6x[e緳{;k)MA.6W+lvBm#I4U9Xk3 [6{;8۬QSؙٚ>"|[?-`RتAoE3y27/9tT>"`F*ΑC%ܻ5N`< q+ s7\+ۑECbz^FՑ?\ccmm!<Ï\'؈y:)߮Y?8OK-"qf48ʸTeb7H:WMzͿQn8\붶+dI^$cLm^rX;-[G~;yHsV`;!t݉.:S/?H<&)zO amoUl ?JY ۜ6-•zpv.ő˂qem9T(Nfjkr%K=Y?6{*`PY e]MlA%r6MsUEU6Kд'IILf7=9bDB4*²L"Bw9|^#dж0pQ``^ʋv]8ԻB/~2vr3i/ rw9 *3倉 NADc*'0)ѧiS9-a][Z.!LsN2£ϿX/Pn.hPa<쐅w*5TGWzOY~g؜#>8ڐ=Pn>@ 䆢'AwڟYh+vb0jC*FذgP1r7Aܟ牂N{BC?})H*(#~o+=z@5yuWβtUIa\܈ N/3϶zqsh1 I463 w@6O/1"U^[,2Ih֚N\_~DqH!VHw54o}ں^kojiLcyr/9@-MA,x޲"RUd/4^jLgp./:ǵ [C# !Ge[掇-!V=zA`%UnȟHɺ spۅڅ|gZsaf#r9)}~CE}|0m`bqӸ>CG鋛VjzՅCqW(Ae۬%R%\a*HvW 6i%6%S 7Wytif X,)[Pc- q|Um-TpTF8SGEd]n|qڊU*C}yAaPQ j| W\ rcqӠM晖Ч"RqݢVOqqp59ThFpm%qTMgN2^oOy9H_fWt`5MFND;Dj'oXԷ2^=>3)ԃ[1*Roz pݾXm/`OɒNh#zV{6Cݰͥ];cAyD8(/8F ?D8!N S5Yߡ0Q1[|zSҙxzo {V} uf!Gܨo!u% mkO^KCEG'k;$xWæH@r #@{Ewvɐ<,cX whZl?9$uIg>ܳgpT rI ?_7:1AG~5YD,S=$KLΣ2ƣԈ:td}Q%۫,O,ldĽ oA+Cjc|E$,fl[j#_/&ˢ;|uQJ y%rɍQgvx9%-XS ~ڮt!SxqfEMJmob.7?/ƐvLF8lk&A }B~34_sb`U[nxwX s\$F,17ފ[>lJrƗol-+’ {0]q7jғEDPǗ8:Y:Uny88ŚL#9Q+pHi^C \Mӳn)Z2Sg;5HV1,ܬ^'<CbS_YFU`Xd3(:JZ {*/F9E-I>"=)-0Aĵ) 9=AMCah;NXX˓55Viֽ|5d˙Wx]q,æ;R&`*P@W[0ǹ@/l}FUB$;?f嚐_BOȽGl1mf JWP9Mkj=<665k6#.PX H~R|%6xwV7~嗰-욏RJ@[B%b1#?Xl`Rn|Qe?û !?#k; 98GRÅI[-/C6okWjV*)g/${ O73ç^0b5-N sγv] ^=.OHq|)r8iڕrt*c3 BTw\uL]Nch9,*CёN*lU ZlO̖©$ʔiﺙ%}Uنpw*􀒢N}mD-4i $OTwkӊx8(f~h7tx UyJ5~ؐٯ̉Δ12d9Rf<pۨXna.S#"||}ЕQ0p=>?w а{aN̶(^(5=R1ψd( A^ ( S ׾9U|lui}MĚV*76 [ikG T9um~l>f 7߃\Q9 H1h~QU;L2s k*SkAhWvvtW8%pJ_t!i ZV%Ez%,7iD)׉_tK%bh[$=+*\(ZD5p+ȄKBHtÿa,c|I#tSyA[->^z~1 lOT]Bv RhSܡj"A3XYPnQP_pW=\u`w y.*=ڪ3U*9ӯ:(4xh ^I:.s;C6ׄ"~{N6 =$"_|2@T7YeUy2*GmИϝ9XelY:I`8_4zy2*LPyy.+ٱĝUy/p_aU4֘WҴYljt6Yĭ0.֫B@O1غ<#k7aMCBQ6zv^O"|]t>{y05r TLl DUGB%>XxR71$0WC+=ӨK굈wceW< rt(FqlF,>5I8э3rawԒf+a8E0AR+n[i2 bq}S+;נYoV1g^-v7/a^޴i1I:[w tf%TЁK$VuT ިk7 78UCDz||6BSRp:Z&/TG[/gm* pNO+lc2 x k*{QcBTAؽ8ӣb\]85DgZC uCbr z۟1~R+oCZo-xػMAvp*z vΰ"UJJ:w vE [UIW V4Q8·1A5kt!4cO%Ɍg}%b+3Ӧ۱:?X.z4I)n!ҏX`P"r (%CWӥWlb#ֻUJZ.9BD4c,൥16y؃(n[݊H$l|޹eLR>VcK_2Mr|x\u\ӈ['i^NAted cP. bw`mNOH3B=$}LWK3Pr8yt}s=b >VGᏄr%d"\C+L~v6yAN&"IUv)G`Bw L9;!U;(܈|i|*Xtξ:_A=QC: "Q<ǓTUt%Hb=Z] *yƁnUwJtȩ.&uFdive.L5[L&~+>jlVإo@,~#a.^,ɕQM?%bFzZƦ1}xuig@mN gބɗQѳ3ɕEF bEs;rR/XEHzy*2KA?S?v3;@ac.QtGR'p6r΍T&( *? Hf7BdA8WBeUΟͿ!5XJ6 3$I]V,XhȺNd e/z|T {$ 1(` /:zƸAСec]P~U$zifxɆSuyt-I;n48j%v 1-p1ZLD^#=m3+^!=$  q' vVߩt:O_K%A` d.@n'~v@x;'l@;KW[ӡQ a>V/M~jL cGE'ԅ`,/3(37)`e53IsWcVwAXb'9aVػ]MjxOR6j ST-|`R-[)n'w,h(/lxE"lj½gt:3M?Vv4s$ʔ.f}Eop[b  :q$ McY 2$UMV8b.;sF\܊kH;SzeIT#q-ZS'kÇҊL ,>Na&y:8\3〧cܗt"F#ۗ8Lu DONVY3iaOEyfͨ<:~v ǐ-M[&5=f䏿#P{ ч-בwŧu L\u400Jeȴ$^L?(R}ٳegH!RU#5Ds$hԨ&X2utll-lMy;*JoQe!(^^óقaT SԚLQ .LM)nZY%uOpog^pO aodb}t7poz"n4mcw8oDq )kW5z~4xKgZ,y=+inJZ/wjrj"W/H'b,gLȁS-*oj5VL*ȌM%6|H7h"ۑi K-iANg}5ݶ~,БangDVR!#)lfML-,j\랇DpcNT:9d)xĬ!0I ZQ"+p1z&w,b/'2Y|:>U+ F)/$@pjY FXAw)7Bn G c HDEbj]KI7z8~4~%aRc,aܷ(r rP,#r}EE;#=ӫfL%g<|w 'v!P?<2!Rz(0{,CZ&g Xɑ(|px{Pn.| K&ZzB붮D<Ҵ*ITU NF5ZI2uM'h켃kȂ]l"WBMFI(wUj㇌I &;dh2?*]`CmKg Cw˳3S 2^,xZ^}>sN6bKP+^ (J4la)VX!X:ApIlaԇJ'sS%jN117nSl)[Rߟw_ dyT:Io9FqBal+e1 G_*L kF'EE.?)w9N3T%Dx7*S.~W x~7z-,>RIÌbH3u،anq|'~ӉseLsNdMDGӡ*3! %Cm띓 "AnӜ$ b1~ƒ\;)Ww:B* Qlʹ^?I5RJ"?M`>-C\:Y.b:uj4 }#H0:F*7 e pa9k8z:[\z]D[5*=pG4$9NKpݬZ>LȹfpH3"bG5aS}a RhSPZ*Uzs!K1*CU>MDʍљ diɂm `AajH^5Ң]uʧgW;[bTplE]t 7uQk;cw< u}c |7U!a*]=Uv R;=]Oڑ$(bN/ڊcwsp8x=^KKJz;R[9K1d_!> H)\ST(UsC<+T˞!L<kN02&pk~pkuɃ\y g.GǚyrIlU縣BUij4~?1ɔ[G(*J{S2xϊѐ> yNA?ʻ3%W?:bONS@n7}SY)3:jsI(pEecZ jp}5_>+OZ2|xXkyx([ȾÇ<췠zZs?=:m%[_-ƚaHA[</wD|a" zBC/pS?zpXa,9"{7$_>r[. xg0[10u| IJgޅfrG& QVЩ^.b8RȒK% ;eƟky % [k$EoJbZlrX dkY?t-_~NT:FDg*l9)ʦ>W27>AE͕O,KSp?Zq+|?bk/^=85H9o]ZS#,t*^S?$Xfb*)g(i]C=(9u:Fz n˸V| j"Mt3xqˤz.C7 *" /(Gt*vKn(c Uo+~YJ? [&3*,y#b|EI[w}bm7"qpr M6IGvmhJ<ؙxu~KҸNA@ob$6@C7CYKI|vV-*VSF9dqp*sWjdYw:6% e>'1Vo%gfںY}&&7 Ì p,a}U<ۗwzQ/֡{՘Su9ec.9tI/BCsZ7+4Zx&qO0>,>~-e&uBF[r[#ZQ. d)Pe7s?YW–'VWf2r}?3/Vp!J@ =-uG=\%8 J / ~؍@Kz r\.S*)H@2-@.|. ;+l/A(&vJ /#wUkUĽ,G\*Lkodtr {4y`i5{rBm 4z*6H,N?i D(B^%&}y,yIs/4ƕl|mk>\h_8+.SC[ 9r7n [>dt)'3``H$VS+t"XػمK)65?DLQH_$1nlD9ud$D\6A勉Ȼ\8M׏_>=֔i>>J} \#GҠ,hҔjP^2EdW=nW.Y?{:䞗{Yl~I4lZ%s .(l 4D%:~=Si?qVN[k9,aUJIEWLƂ`u-;_Qpbr%=+Ο]T0=HbÜ`3տPEד{x(\ *5zlsH6q䟣xgmsQ/4'rhri^TsمW亚b ajD^FE'ЧV͝zeu>~捧 Q]+!\Q7$sEz$AI{(PzW14e(KL8Y~ۘ\*YDߕA4]rJSdW ɪ}8Z3 GxLk {jҡv^XC!:06U coo`MX0Pl˗JuŶg{>sy9ݑT)dQq.B\OG?#Jb,f 3#}M`VfIˢ~WtM*62q.;~kTgW ZƋe IJ{4A>*n( 5.4lq PK]@Fԅj@\J!S'ea=e5Oy'׎1P zjNE-G-cz(`.NXS4&h'Z%?/U-ˈl뮇 񧩇KCuwQ9~>qG _!m@H;:_Jel񓍵H۲ТrQJD)[)IL0MkRQ a|M;LGpbPa݃Ohw TL\ߦzye$l(?:9Ơ$nq))=O!EK2pnR0 rԵ\A>JMN n' O'a}}/AXiھ +\R:8W=kU'7uY14? mV@:nλ.>Oˍ*sjY7 GdxӍ5 {Kx!}Pg2G&B˨RbT6>}L;OHZ)߱yi UG/$:/XsQf3bSyDTVOi14^TgrhT֒z6EJI\FM&S9"]\ޡqX,(j1CV:BCW9>(姾1v.ԛ:HTJFO)%T)TƽN~GڎRnK“CKMyM7DԢKW|'5#2y#yis&K~CSgv ]ц=~LpU !N;v1M%HtS{5l1]*%xMvXLٴ,FC㲭UNVgԚ<[㤰Zt~J: rYŭ: FYW/_D5c&įwKæؐ]xU3U$\KCnz}'JEM$@&|jDzЕ_d5jԸ"!WF2TJ~ᜳ+hz>M\k[ Ss)eNR '݉Ux #"ɸ_9v{Plt!1 _wrȸ92 Hڊ ,2{Ea?= pt E-F wEF/$vBb'Jyک)KyywTMlg$(5.F~Qy|ZYv%"rL{_S#j9[D,l/T_.:yJt;Epn7k2ِC t^sNzx hX/C+ș|!}Z qW:U~+R n/- 'mHdO-5N/Q~Z6f۳ D&Ůb,LR>EJBPk zz y :pkWC!37/Fq,~H-m oRZѳfl*te9}TLAz :mTxP?Q癇V4)H1٦Mw>20. D#uCGm 4|;(n5Craq2o;HaknM*#f @<LŶcoeMx3 jsÎ\ld4"TJI}p4K4$Cȶ <Ԣ/=:cNG|B1({M}098J|^e@#ˢw6PX̕81m疲>( X9ж6/kA^ƣ-T$xƿEX$E  S(m޹hTM&鮵)rM}PhuFlՅ9N86=S'RBa P"Cx ѝ܍IQe#Gz qe;% cIcР\ )#7̝-3XyCiD!IQʹ#)h;m?^NR0SpRsrA,w=E\D s Ҏq\LU~+(EX(O7:@&%2;=)}8$)H=Ya"Q6B*&+n/ES]q^F ?B1%N޵I,<}M6(7NBtfr+W۷h,rQ"wTw864tƝn`f+`!ac)ڂVj]e#[NhM _XGwý|9O~|ahozP P%p#ƒ VQ/O#sTOA@?dT"p1h.\~tar#HFj]̒E:4 Jx[ƽoDM5t6͟g". ؒs|pL6bԩM{vtؽ65gb8r2#˯UNn'tItq!\e] [7lPt*ij-F53&rF#l Fx.ҧ$\Yur[jZ6,y%ԕnajA8GWE#uW\uřtXp*@RwԅcU}q!KiՠBw-%RW9B+ dEQaJ%W\8 AL:s X&JiU;$9L dNZ|t ވnf9VՉvsO1!Pakܤfm Rם/{X&{TYL$.όB˶z~u;ZoPY{BEø?d'[.+aM_Ü0#CD2^%m,UxY!CTj[xCD1K*haZg.7P2@I+h UE%dIrJQ"ƺ/LH-8$B'|wnTY93 ~|]3{ xc~@&f\T``BkCPiuܮjsQF7:n?`_>ͽ&9ѹB=H\q]6`oF5"0O?%_;|]d_F$)k~D&ODf~zV?z e>D8}u!a['2ҰU0ܭTSv4>)zPsb:_`<5ҼRCJb^SK>D}t<ۖU^9Vk5~w,F8"йIOLf׺:Β'ʉwn0c(G$2A\?C5kv0H5`_ٓRI+hYy7 6`Toѓt3>2Pi\XʛW](cߺ:5R=BylArFeH % hԌ\i ØɚĚ9+a5[c!Q˝J&AN ׉}rXwioې皂A|$KUKȺ6R1,cqYկ:K~fe.zuQ"R}k/.MNmޅ{kYo"#pfi$43 JBS}89 gl]_z /PJ.{p"[mV_>ʚ7NP,BȢTJomZh-A!3L +3rpT`y~oxcZꭄ0כeOOBu:LùƇJo:`$E?/AY}b ;֭|鞳-kshчXݰ`Ll$D}cy6Χizu;M[3&*f9H.rATYD "-~X@ҵP$Ƣd(0o!E:5z4M~ڌ̻!qQB7_ϯ׻<Ӟs}P#X?X- K)X#S R%6I} %3DUPA=;7^~-jb_7O6V{AQ!fv7 Wr)G^2 3kHHp۾.`ʋ%'@rU u45>s:} ;T0:g^5V˚/uq-rG!љd,r8U"R#t 7 B0k:p_H+u]\N lZ*q=lt4 MfCTw?<#SJKnkiZp @o23rՊfq782 _g{{8Oz@Mm,@ʑdJfA_Hxc`Pm[%ao,aM8>'8$Fd}r.#*/]~Q_z뼿Evf3(hIȶ_zFE>ꊞ{ޝv OC2 WPoLusjU͊Zb9XQlr4iBBT.OL d}M2TCmH{h4bSx#ҤyR ;v5/Z?\tsvj.;=/1$.YNcjr}K $Kf. )HeT&?ÒޛHyuc6s 1]@Ҁ)Bw"8: 7?KAUDMسS±|JX \ev^ 69=*It9X"UdbsܩA`wޮN ׂTk Sc;j0Tqԡ!UmY}ΙU̻t@r1IX $ޟ1Tj1G#[cH[7XuOd~긯zIrac."ḦOYi;"֜:6ޠT^I}küǾ /G0vCpu{NO]Jgb] #8d 'M˭yW[|yx*9ctOƺvd؜u#oYxe siA)խoɱ@lKԶ )擏>X*6 mA QىCzZuχΌS /C'P&('Ͱ'BwjXܦ Z5z:Q1=/烗ŅTȂjd+u5jLDH9x)*CDoV[tH|KF4x_R6w4@ J[& U@vWd[鰤%44L>Uy|!B#=O:R3d aaoLO2\wq:R+QGCq!}LEQT +xJ"&?pȔRb+YJdr5a/0jdNsaN rQ9Y ^\T@w*0LGI,AJ A=N-Ʒۋ )zL%r҆\D٪G8^Їy:hT[1gt&d:Ζ~AI@ mi}*S^l+YU!`%~3!gkLD-~$XyB^7)?{jdriÑdֽw 9z MC߶I阘^tFes"'\$%[,3۽Ho!W.m hskeuP4WL*5/RvR?=bPwRL ɦ[A `{ 1xjJ Z6+9(:Y l)@/ jɐMr JAs՝A&&- lhXK+LCyĽbx+HaQGdd {'a'u C\v6~}v%EHf@;[֐1foQ JXX> f; 'N+B0]bC>5+Cv8 Nk/LOok14@*^69F[:HjkEÈ)xOr.!C!C<76in_4d 'QPBDb]ەdQ#z$U<pzzxv~=@a[;ӿ*nu\xDmӣY/!~Y~|gct3$Id: 6{^83a{j=Ʀ\aDOu!̖bߨ6( #Ac2; ':QTG'AU8xm/tҕִ{.#(آ/Izj kLBZ_GͿjj"ZE$4Tׇ2rZk ߚ$W 9d=ot6OϓV/a T3X%-0-o&olAluEP;~dشǀ )[3QꢉY#5 㻼a|vn]ۭSZ l3taVbڦA4h3(yKI f,z5sRREȇx}]l_*y8,%v+$}VS uZ%`-o \Y)Y9ĘQf`qh _Yf mU)&`BА'#TdYlx9b˭^"< ֒++S/<}洦iP7k) ( V_W%:a&'r)aYW)KRW@hlUJC7 R [y)婒[a]jrO#H;ø} ]M0mWWaI^I_>"Us*+|U-endstream endobj 230 0 obj << /Filter /FlateDecode /Length1 2369 /Length2 14975 /Length3 0 /Length 16372 >> stream xڍsXݍ7[elu;v-c-X6e[9\:?Ȕ՘DL &6fV~:+J d A:X9CFh > YW[_Ag~Gc7+33@H%lea {O)_Q;=@d {459ZAc%lll!DpYT.@g7௴vcF[Z`r7v[+S X #?1m?Pgyf ۺ8݌lM  )0 ]LA..Vep% Ŀh 4Wޓ;{VfbȢao )0 p t=L-Yr/28_oGG989b]d/BdcY&@ +{?d1x <!d>xm=,ڊ '7[L `bpk7Q? ؛;|?AEX@yY؂;&IW[IW#alge`K^[T VY\1xYD-oL djo;l.V 76#nڿX@W {S6`l 5v..7xèr g 0wpF\ѿHF|+EbHA?XF`+؊`Q8,82?Oog7bc3]Lu5lG FƦ6@3R=31qmϠ?wo`/ ? [O`?|S#7GL\?!rk uǐw,68b?l#e?d/G%qSsNp5m]9'R8:f&(:z>`_63=rwr+Ik;ؼ? Z^[:SWgp@_g54E\^t0鸯%tgڟJʉk էgSFșwǛP.4dgBXw>Nf# Θ>(#_b'HK9 JH|Z?ᑓ!IEA"cO%i[?~AiHM34:HMg1:-,pχI!/M?wMt?ZvʉtA0E0^NtQi%\<`oUwt_DNF0w<-Sv:='M{~jv܈b&G1NX eVԔűthk7ۄ}Io@[겚@F$XghsFrƺD> ӴcGrۋX~꺼lɻ4 n:՞a S 3l e^g3Iܦ8D_)E IdUdVG;l!}[uz!Ei=;`L*faViMt_"ѵx&X VX0~f,;m2S$BI@_MTCAmdƃ?DmCi% S`FտmPd0GmQ~Ӽolݎ~Q]1]W7DPvi@ w-pۋY4x!AԬ26R ӭ? (nxfԬWP}ؑoE?ëـ9& s mV\+$b6Ae+*)C-F(K鵼]qD E Kyݸe4Ĝg̛oꬱ!|硤Ǝi+\̏N\,&phf:V%Ȇe8a;tWMQ- 9L -(]pYYTUI4CHü8j(^'dXRXCS0 Z'TJM ʼn0:n qzE;>t,JNwc3~2{,`AA|\r3>P~7L⦮spQ%I[lA*Rn)+yVM4M㫢X3O$3$O^p/ }ۚO}fՃW漦bL MO[.DӲ2)~0Zw"N&.sذZ:ͨ u#*x{&9 n^)DYiyP\@8IsEv L}a{)N݅y'XU/䔓ih/%Lj[TºDgٻa89sGwX& C8GQgIjq~jW6ƻ!y$Ȓ8>f^懨ZTr3J}:@4tDJX|(I;gW80їYuxQ8c5ӫ+fU^\ΏmX$|AXB!'& sZC3g5[[{FU g-EfE\_}4qLVu1E3Ã9|G*Z)WAJ7F,X^C ={:VgW{ dz-^.rb^cBG5%9 /%=;LNT5yVx(#ljN9qꟄ ,a.u'Mhyc$I PYQK1Z_8 Jce0xxjGpSBhn7.D|Z/06Gń2̮Yto.Ë|_^4mHF*onZi͑K[< ; k,?3#=}5Y5]_ȇd-,Fo7-|ve Ԧ8h}*C/эy<}IzvpW<5z8}t(u^Hm6agq1J/t> ]ŞM3}C n;AeH6䜨g\#0yֵ40s1(NmL]'72C^ eŹlB9äL.HkEoWN弨u] 0<h ;K*ڦ \h BvD-tVÒ3H9A Ê 1I@gO) 7 eߥ>6kݻ`ڐ" j4wM {%YC@LVN3B9tW 5 y>8Tn39Q"urhL:Ⱉ^lO(Hg9>ݛ\d yF-;SZѸq:cA|y顏$IX)!!5/.nȎyܹM7:x8(Zol}{ )< C`LJ KdvcE' \''woQ-Co8(|Q!4&~Uz:>ޚn{&L#z_b"( ȹ+^06yF8A|W,KxI8ǸJEA)le/(=Q9}ka&|7QdWP*0ףSf)7i88 I &=uDx440ZfwmOf3ja+4o⫤$+62e* !+VOj͛Vrtm-_:=$(WfX|qW 4LXk}$oy ={:-(R2>9qiv%V#3؁䊎t1\psd~JG[Lr1=p/j ԜT *,]Mi]) rY͆V8ʟae)Ifz\ 9iUr%aċ5dW-YWX~UfO%ϥX5~}Ӳap&yˆ8Hֻi/0 bF$Kթ,fuیz-99ſtc/jJ/ԆnZDZ!;_Xi.HnvhwZ:iYg~"v3"hRh{e#yR~ C mN{'"kJ03kbMn[SmaqmOC`)qS1Y02Ky/dB6;A5wxّxh+}­j`/ӣ9P$D1ޠed&zA~Kv\Ǧ@f'qQ܈־j\jdչUE\n5j軹zW|N7 ߱O(De-yN`ռ/j2ۄ>6R Аgt['KW򨷞d8N[6U/(7{;Q[׌ Xg'Z.c`6?hB8=LR #}uַz<Lf6甤34(`&a"ߛ47lgD5w9Ư?xI}ȇy:B*Ӏ^y$2•=MF2~ ިZR|vhSXVMmrJxMƷ뱐8v2E&l鑞ӄ_ ܰAt_Hl>7{hR0mSq ((6`x{9(2A//KXyBpcqyÂ+">9NQ]Tfd`# 7dэT=;8qrM D@_[!wsT$s+oq@ÆlsCZ(We&3EIoKQ|K*]>&!+Yb9Ɯ"aM|!]Vxl/M4QWE|_?) qenD"-[%/nDOPr<0Vvq5+.&m^J/Cb׋vJR?_&m$[{W#myi.db:́#O241歎puJ\.`2x+BPkDj-TV/ܜ15 #HN$`-F&󋀫|\xxxd[7.#@;?8ZMDŶ妃 i'*`~Bk;U"ckJA&PnҀ~*sqqXs MV=E}>O~k;o6[jd*TI|k?YY] JwU>8E,TWGơݯrR+}-~ -`$m0pGIc<vYr0!R2`/ dKB}FōkC"JnXAL%iT#SwGJb3M /iv/ b/LPr ) /_ŦOx8bmGumHYf43'ª RH>m[`hAEY(I7fJiJXKIu)`Ĺmr)v.:FCvv-N.V:隲٫Ⱦ, -xNPޡ䦡Ql+V} 9剨*v* d =Ξ݊H%E,)ZU?z lE}Ke=ERL;|3V~<"0'ꉷB_Ҭ0׼^v^p)\c?[3 ^gJ w ў%ּ;KGfz:AwH!^31oO _+B@)AxFZXGQCM`hPI0󆊯P[bEt~D@~*]r= XcJwu -51_>sz&M PBv#:LOvXuHhqYLkɨI[S{V|7K1a|Ș:6 L1q+ om%ξ7)zQer52#|LVS_Ak cR!nPJ>آ%5L7holWkeV 剫! ^>Ŷ bÞ#RKp5OVDEͻ'M_Cj5kq[j|'O+8mᰝwȷ*B5B*x=QR_O+'\G[8brçNNn5_ )DK]"|$u2a# HS3p?g}#P`wf@el*g  u*w VOV"TpVIZE=~~eiR$vfJߵ;g ۈ (zQؘ!4 W qG0PҀs(N(qA~ppfɆkD̥aB(SQg:2Y=U.2_9P &v%:}?`W+kd$)!#ɼUeF}lKҐG<˷3G 'ݻu 0 1#%qKdĵI_JP.B5pšD<EcIFRk$_GL6OFGߕ"^:!ve#+Gƛ~6gzp[хe5%+04%?؍`tیv}E֭1faˢaж?Ú AY+nz|DN/UQ%lE9ꦌN!ӏ> +36%BK~d>dȉћLe9ҨfڭrkPd4> uLLNȂ+Oϼ[ [Nb$< |ɤ=14Sj^ ! 1){5Z^U@X=Duo(12vc+ 28GӿpC>ϔ :Z.G~["ġF1''2v ׌+k=/N}4o9Ic=kWkLȕ e=E$1^5ӓƔz ٛ[=i:^}:B̲|լ7N}ʦ*^,DxM,f~ y~3ކiĂlcj)0Mgp臍Zrju.u}R48g3 FjcDLQ4Z9 ua N>=4Ŕ,]| "?զ8=n?/IJkhEaG p{RF;&1X.Z2rdFhF`E_@ m# A-T,齂")urzU&tn\FI5v?&| sWSvwW,$su}9t]XW35{Ŀ6>w@6qLm/R#|kG U7)%\Dgzj8!jt3b__ ;nkp8q7XÏjd6`q)! \(>fIɓ]f!DzҜ)N!usROI=)xӖߢ0evw<8N ,39Ysc*C ;zUXA dXʄ#*z$ThJIE}nq - 65؆qF bʻt xaUh e Ď=M9po L!]=%qOAҩXFE55"'>!/륿Ӛ8VP]>k sMs !SB C9ҵ« et "Z LJC@%/uO/Sk b1e˘Z5ruTĉwCВtI 40I$ (M=t/ab= )֊,Ӟե`f[>K9lsN( m^鐁Nvg|m1,f֜^ J=Ǎ3~ 31W[<2_s B~ŸuGDt; U~0{ AӸ{ aQFj q3&aCO@M)Kѧ'["3_pF $V 1JLDE5R#N%7f0R oMiZͻo=!jWo<8XY4%:԰!@?xTn#)#옾IAm PH&wUгf~9@ADJ/X!pju7p*rOsѦ@,ȹLBh.uC = 7 +@]ZjJS%sj"/5+:9Br]?qXHloU:?m&c=1RD> jƦοg?VmeS)>Sv;GǤyÿNW-Ts7=h#Zh f$KW'w&FQͽV?4"䖠]{􇏌HmVL-E%kPx DsQ-g^t4>vdq@հƅMl님|9ku ?yVX'ۢelDʍg|#Pg;;T S$"U0I{/J& 2̘ԗkUVƁ?VFZ_ت↘ Pffd]PlF%$C1ڍa2dφS=t5_4,b#}@IӑhJæ(}xv!m'nܽ6-ʄVdr| C//JSNslw uJ}N".jbzr"D_L lg3 ^礃5೫D#ٵS5O{sp5 D\5+]yKͽ<ɈOOt)gZ\6X,/BT;=΋w'$nҟo{6XeΜ6{o?I qƉe<5S7J r,Ͱ͒H´F z}rH3ظmgGW=dB "OB8_WQYBON̰Gʋ3$Jcr3ڵrهL=q^>q+r 6!0z)AO'kCu9"m>[+ Q5Hi.eLqw~LӒxx:91cKz" ~+&c]0 ")-7ݐ \7RCC?QPGy͉gÞxwz EU!K?)6x^-W~?0E00w_|;QϞq2[rbd+q|d yn ,u۽"+/*[^nmG,y݂7w8u#[OJα`:AtxGO\;뤋|Aeqr~̩b|wE֢YW-OLv9ZZX{,>J&Zii?+ \H(^  LA,z/&f9Am(k^QzkDmoOk"• FTe|u2rXo iL̛AsLR񘸟RRx$ N9J [)wĠ* bVE%g>]Jk4\>/R|idq2 Â@cG{h[{}7c?Wc}1fbrWz{Ўgt9 .A!{Vmw)bI&^b֫`25xd|c.\"`aR^n<Zd+؋Ӽhr|2QUv^N3LWߢ,f7FlDrZhSc{]{P8VS"L{-*V,6&h䁕ȡŞ4x1%3P#tV/qC*1=7UJRG;%X'57N8)[sGqu&gCqd*3ڷTw{:BLJԳKEJ#~l[I7VBچ k0p;~ݗRD nĴ&zof'aq8=a4rDŽ`0$e_f2}F)8;NȴdLA\xxM"uF^?_񧐚^ Q|Jh* )y(GFђD BGɁ۷y M O(٢8IH(o}+2hFo3wbCVGf~=g$5tSXk\5YƘ$@;##G̐_٘"N=2b )hM 0)UpG-sS8qev="F9IU}ZEKwt0[;M=4 cKhUSYsMDъ~`ym D{{ΏP42OU&yUϪȒ uU$JIy#T|(\Ij(yJW|dڽN.H{&`Q_Б*jL@⬬74X\ąwo:EjKVY7sYߞׅ3A)g=r+GAQu߇dOiH}<]ϗw6bϰS( /^><%ku M̿Ne]gN`DQ+1mfr5]+/\`0T4JW ⾣fиe=Z_>hXùO#^/B 3E l{⍨$ljQOmF2wi8scBʙ1&u]*}FtB~߬{oG:&FӸU룐:JOFr^1ȷ A(c&8TˮRu3J>ʭ5^"_I>YBgN"6qpP9˸t qG:0b]f3Wm/MER^> IƝ-sr/-"FtwĵbR?y|hPU8[2ߙ}E7# eer d-Sk-b7kFGWjeV$[HQM4:qEI >a+ڧm('׵_'L8 륡 t˰MST4Gr92un`_e42]\#%-E+ BU 0s+JYd&I[?D7V$"qj 0DotG]h}[v)k~PG6fw 'tNe4Q*?d%,Y$Hœg4SX ,ߨ.7Fč'F቙il*;w4茓J2\d&RK ʹ_cL-x>t:<ˡCaj4N{O䖐VT g`,;A Ѡ-{7 10|jD 8X1xG9'2B[EI%9i%$bhCeuI-vة/4Nn!uԵT!/2FJT 5°л 3k6|ޓ4iX\ai-:<x`1R`"u>XuYwP^~=p& YfH%z(Re7Z/ǢM* 9=X瞄#1Aϐ_7GOB: 2>|FTp`a&9g:cIyO[}y[a܃^\GIBѦiENz%4$9j?k՚m: )],%;`5%ߙmϹb,pL.1QG0thJ ^ǘx /`~O%9^m (q^mFSd[f 8K:&}=?*M$b~9{lCê:ϤSrͷjEa.04ˍHcc)oucKGe8ۖ@q Bx6/fѧ% ۋDIgd'ǃcC0tY%s=/uֽ;30.BS6 nX voZ FO.@7t&NȾ"ZAswRY#CK4\~2ŐЧN (JErr0JUTy}㑅ےgZfH"/!v463<9\&U9Z$tN$%$Ȏ:+-mxPQ*424ﳋ+Qj\z+حl.03%ⵖMqNt#qܓKm8`-pnz翁yxn.>}Q4m|f$S` rGw菲R3{ 6 {A}Y9w-Аĭ?e`tk>* )2:rl(#J#~J9!eg?آ+3F\( 寪Nw-_0,A/>O̙>w>{y$.w̮nFendstream endobj 231 0 obj << /Filter /FlateDecode /Length1 1467 /Length2 6505 /Length3 0 /Length 7502 >> stream xڍx8m۾UL(j7U# DĦVڣU5[ԬZGQ֗}G#Np)AQ0u#JTL@@(& pq18 9 G!C`1U0먇B$! @ߎ(Oi* QHK wr`@RRJn0O8107lE0AA0?R:c0"">>>`70IO8ah7 Ev&L0u21>`O  BBalu.Y/AAJ'W"8w0A~p u1A FQx7;`~o PW2 CC<0QW1!*(77&?U' =w??uE|H/P/w3$  sa@) qBE~0s6QG, X @a,(? \@(8Hg0ǿ{}@@׿l n2*+|BR!) I$%Ao ȨtD"=xQ> gBoiWU#u/ⷝ/v#x`Ά ;!v5z0(Z0vFNX p_8#a(4׽ˆ=+nAc[N?!!(==~$X`WvV0#Ql1$XQ@ׅyxa6"np_(B`c CA<=[D؍}W`0GD&eDi{ŎDq Գg],qe{h'eQcwO} O.+ q E19H>]K2bƷIx)%kEz P|LŞΌy۱Њs3`u O /S- ܇'m?g|6ANwDU #6{`r?#]Rv[YX,--{^rl5_̫I_%PWJ\nJ򛯒ckp*sUCq2yl+ TI鉕.xb_Go?Jڤ!y,a`stt.a1gwY-(y/V h۶}.+xhe{VfRjs~5 Lӎ/!7a"8/߰CC枢(Ge)N>tRnOC^ɥ >ݿj@ULjm羈(N^=g}m̝DxVx?zI2@n{2ݒUzK&5VnpN^0o>Gŏƴ,1*iE9F$v9798"֔N mq2}fhZ4]y!'bglqBM tޣ"v[Ul{Io>f{erCvސ`I>zg=-wS r tвeb~XZj]ǖ(Qqtx_D=y%Pr8E$qYdc4ѣԪsG+Ki~E:/xhaRd gzM'eG3@rB!Jצx4XdlY߻j׋<ݫB͍doEqD{\Et2O1 FV;g)Х;hdaE;[YEg1/;G,/}kQ^5; {!:B s f2IBJZK:|pȞW};ӲAuu݄ ;&GlEJn8Ô@p;F-tU~OiS>yߺ' 0'Ud)cV-t$޹&,+jP~[wCC"x|0/צĐ:>U pw|BFi%B2LǑق3nGL#`fwZm\]nXkl}w(,v|uԿ]ISvqJjv vX"4=Wi_ +K(v,q}T'ITx4ڽ d 6Ww޸v7Hzg(ܭEF!'Ƥä-Yפƨ`$fD]/A<zr69uo&$x*YV6BUwXIuv#;jվ@RI~Vz`R.yN>Ղ3q%YU :>FNli(„?<ڪ%5}pԍ&(Ol-{ag fZq}m+'l2߷,;8PN^kEP"f$П\-ئ-pMӖL]b-?`Osa۱) YUo}KvwV(^;i0FJ"I -weIeu}[*"#@ &]ÿjӅ;k?spH1rxnҴ-;3qVwxB{k`V^za]/}:JYl?#6= CN⳰g  YRJ 8+ tVy&},y/4 Uz)3A`A:8g%WFIa `W;UXSze4,VdDѩf~s_J>E䡍bij;Jq"]κ;O3WJ+n,{z~Na[ta.腡ĕMz$ۮ<,,N Y[C#` Ϋ<戢aҡԦRڬ0Uol/&Y!5«830˟][[Io`W*O~peL.wEN%,*m. D_RrUҲc; n4)ze>l` {D@0]o?Ct]poᓓ1W3F~3œtkLcWNWWN;[tW?ZU-Ğ?q0~b53aNZ3vJɝ-Wn:ed';s BC#[9Ͽ_xX^C`d']DDrGw Nn.Ws} (g*ao3br|ה+*'=-Yc>9<2z-ӗMF)bse_/H)s(WF|1;OvE:5Ug $͊I9YR·_wLpcw+vgvQ^ IC]G7wcª>N=tW@=e0Ӫ|Ojտr GE T[u$iiDp(3sn+ԛVZBwe'־*iJ׿xhJiXjxolk5H!HSĆ9ؓfZy.uְ>h| iC֯6cBTM׈e'SC~+>j],~2&& #|4zI_ձ|Җ{LYླྀy3k71/0L懴 -HK2#o%ǖX$.j(䱛Ixf6+/“,.I/_Džxa䪣CT:ؒczs.aY8anfk0Xz|iN9d\:,Dz>ՁBӼxs O%3*!΄'܁5 qD>kL}I_M罺€) _^)@~ɶ5i0F!q>uhJ_WK6P4k[B>JOj#ieaӉq/]/*[Q1LL9tt]>RI:+%|ú[")@N8!udl(?t:"R_V¤N' C(\DUܬTHʇZt-*(k ZLCI%kVrJ. 2'˼-} cP_! ʄ 9wk~*H*u1]ɛnU-;F&{ZSIu͑CJ*7N)qO{g w(%W& Bq6-hQl^.?|`$$Eg$SW U~nsն M\~'Ffݦ>|m KWyHNm veb!^V9aڛ SX:PjXUkUBJ1= @5zx$njw)*(z$5݄nsctu|(qIW˔\q+}hߝ"\YuwKHIތqs6w#oX&OSɀ\ʜ:0\:@|p%§n4V Ǯ3/;:a:R X+!w9v@L n.ec=9#BJ΅ OS7ZŠ/Tt ^f(fT5}GĊZF{|^23[Mw  l`qO̘\-TDc}'FI^h_B9Rʟ;1FT~9X|Bթf@&1IƱ:>ξf7<ɉUκN?+mF*$]܏YTl'5e!~evn߄e҈^+q~>c;?bn{n;"&dP@ABsǟTƥ]o׷n(;&-]\fsL#ek3&M]3YG֤H~L,-=19÷.n:?hI,YTg]r{Ɨ5LG5&y.ǀDF&BoF\4:i"ΗO6 arz (>ZPmHBq&ѱW@1SoS8(;,Z\|Ko" yuI>_Iޔےju38r@kA=.M$G|(.sTlť0]hFj}`RDOLTmW=;Thi$]=կߩ`{g7gݡ]ȭ<:>SY+c ӸG㢒/Y{?]jvàR$oJTt,$7u8r=K@';!N }g6m#o"eOr It[#T sbx)`u[z-j'rrYw; ~bb'g7M?ށGF8]">`BԺU\%[ ?[}RPF?mvwhxfFO,O!-k'V vc1wþvGWǓxҠ+(LĀ 3 tad`,| UL)k1؍LbK3K&K(ڕC۩]!]__1 VjZRnCxܝZYg W/SWŇ`S!“arAaFħ̣QU_<m5 iՅFt/*U:Qws2];s!0"DǗKȭc*=. }LIˤYB9#4 2N#1z0^Wu5V(ݴKxv'<;juHgKg'CS?[21aKBco*[V.zfq(H+==kr:uXzDsN}S*RnĈ! ]8jOz{ZB3HV^jKpKyfIo24> stream xڍT[ cŊ R];ܥ[qwwS8ŝz9畞1#\{$Ċ*B&F@q[Gzf&*3\h Ghf5t| H;YY<̜c0сdFƿʼm5/~ 0m}6.6A ӿd81ـ은Ry3!LLL\,=jlnv4xyLd@DCg "33d0lT3M rh33u۟𿏘QUXVLNߒuxгYXY쬜nVh۪h7ԓ1pKGCC mߺ:LLooGWĝS+oh rw[7;9M|PuYhr^)G÷ 1FA@Ecxn*:oLL6rƖowaM(fclk豰s `C7Dbagx0ͨ 02:yLm);Q/ӿQ0AF"N& `X[M? (_VEzSX*[AoAo<54Vh_vYIxMD v_;7RBN4q0|S |co{qooϪߨqڽ=.l1 lo&[F߈;elFGߎF-qU m~^@cĥ[cڀj!<ϳ;KvoUo=VŨ=[Z=cwZ& Uw==YB7CvJg;q(~sp/9[!t>R-Bǯh<(c֑uf=kH:8Ck%~}\š W }lCx?QGqaL cD'<ڲRLV%n12:F?^$;Z#8.. M}zC!`Z9h8y7%kͣkImm--̕FU`{/ 9X].|^cY]W2S'Do)>~$ȦPjM=,b$gL+K*aP8D  %%.3+aTTPIt1\m~iΣ m}09`C$u0k0IvMm>ځxH,< H=l7`Qq,MC+ɱG.{̔SdJtCcTf^Q >_ni/Vz'ivk-UE Sj@Q7p*z{uĮwN^/X0?ODf/J5F D5ҸZ7cjV&a 3w>ؙz0vyred2Vu{NN1) WA[[Pbz6?[}Z=+#ȨO[Of *RZ{TPD cZidzebZkj\p*#jcl#,Vz*Sjdc2Lg;w>FvlML`ivI\΋O0J k2J|Y""E4(0#("} Ͼ(*T>(90ņ/(ڐxa$(syZ:6ZG $ChԸ!S!Vjnc&gWss}q{j3e\c?F@0t1fg5v mTs4t?f?mdH9.I2Tz{"nƢe}vc?ƅ)nl(KJ78=ۭ'jBNaxEc1y]#Hң$zvťEeWF%z1:U29ѵEx+^+<_l;{QkwҩVaWo1A( ɡiC~wBsC_~ťcꩢ f):#R|>,սUVN+)ѫb&:٤>"[>)Rܥx(E¥Ǎ} Yf@Q|(#Ish]x(18G3 V1K k@^Ufk? -]lCQGn#LUEEC'kC|^K#8yr[MG+b%J5"T9_f3F.[IHcm}~#3 ]F<ĺ>xʝ s=$Uh2PկhqQ7 ~ɾ7?Vńv!(Ta4woB:ˋީ"P{P0es;]%?:o=ͱDg/<]elYS%J07mn$.;6,%@u\u=̙0BC1ٞx'ott1FOklQ}e <>M9mА2Fp?x_C,Q=.3w:gAj<- YՒEf1pwШ'v1NFHU"}[f-@4qWً@`o5WPm҄a|eWw ]b Cq=10p R?^BiO}[j|1Y78Q|kzF7 ,<.rSOƷooX91ň2qI,!ؘ/I١E(7=a,$ 2sݣJn 5G}ˑ֯)O"6^lZjV0v+XiœDS,2-}8VbJg)7яr. !aWS #'u[.aYKK8nSx3':H26<!C9PNgҕǜj> (0mQR&#R ^^ $;r.qIRM#!tTl*'xk ~l"Z4& L`~| <;M_=P-4ɭ,~(]%@m~݈݄ybwDW\E|{Zl@T<L8oC+FB5 b00vIႴ2$6* qz䴛&\3 eB$$0ۤ"8>,A}0H\c†L$c04;~h`tog^' lzS[gmqr=u!{%;t9NJpь i[4]ɐ@ZFͶp.ϕkg:-H6,!UD<h͉;I {7țotS^usc$h @ckwA zUOt p>2!,z4nr>?2ʡɻ+M@><°N;龿SFםTt=O03ʔ7gA:+KgJ"Ϸ,);pw[Ћ7mqV654_ ;JƫuK83Hڵ׏Ye :#Nژ!xD EWͬ!O=:` yi×˔l u.;,:?U/é?O9I .KNݽW*}b4քTZK\G41nfSƩ,p}{{>3+ȳXv*~*;G&!p+[-c_Wv~$pJRaXp7xD7ow$^=<0j;ΙDo 0ǖλHUTz_FstUf 6\OC؟(y ^A#> V{ų7$9F3$Jx .vi̷uS Q&~VSBɋy}F} ڽh<:G IGiRwžs;FaK:;OT"աF,KܔuoO^*>tI FP'\g(A}^uWju-}6`2@>lI /j!v K5G0y"?$l3m,u\P19ZhclزbwEђ$;&4D{V'؋F-K0\ڝqqX ;{?C3(]\9^m"^PJ!n (HF:J#>8M0j-᠐J^ע' |[*3髯rU(<ѩNK}GRq@RmsD_7!(Z:[yVn\!ےJ!u){i_ρ!KlŃc/U瘄H=4X9r;""W L3$T< ]=3n#Hssz|d krhhR/X R&ܧ)RЁ5~4h+6&Ar^ʚN)FЍΩ{frZ}ΘfA{cH=-6e}.O6օ(h`"h`[7u.~pEb)\5slk\#7AA@(`݄*jH Wm_|B"f딕-b>+7f5?ʢޒ1(e-7eAkaU0L5T'$s.0ngAn5 쮍SFNϬ/c Fd7e1̇ ߽g<~9߮4c/\=H[î4;~OI&s;*]r UOY[fD!RkT!H S|$\e$MO0)K\)qRS^APGyd 0Ӻ9{RVΕnWKO&ڄh-.x! 4T=2bQ34˥,1)icJs۲uf7~A?~ǎ~'aj{5|K{BDƖįd TJ@YӉчǧ *9 =YKqhKoĘƇ^v[V'=Swo[wR^yڕ4e&oڥg 8wnSia;^<r4]L(a% 6c$ Y/TX: :;7Y1 $,]tEOO-OJ:FD"s9L ;qnAvsFݖ`~^{؛(:#x0K'ܖq{{HRڵ85OL$L+|^/w a8lE[ Dw/VC\m?L3=z?J.܊g8I nMda 쎺-=|) < gR3aOb~6)!v{wT0 < 7[>'OؐPAQ_TZhtG 7tlFVpSj0*;> e/@y `PWWeL&lnDؠt}xaz@UCkpGrS ReB#,VV'QJ XE@`;P.'ؽ˱\sW8ԍ0, vD:,4ը"Ixtm:)YAQA=AϬH7R;H rY^_,LN8 8*s|i ] q/l8۱B%@ڑ1<YCTD=+ '6:82< t-ToG8ǭJ u}R֞v#&6- wʈ Br&? OiH>^L'|8j32> Qᯃ˵z|_C&n) >8}/Z3aLpG?L%."ge,fĞFQ8CnWnoGw -ĉ BYEw߾*᜝Q@Qa9~CdFfITWR\;|8)2}C jJbAЗ¢r9'%{-ZYiBay 7JX"р/a-`g*wxh驲J$11N-3I(F Cicld^51x:] ="mL5ANjv?f_uˇ* 5|Fݥ gΘ|3b& $ᗫ*E= ۠BtnȮڴίvĔն.ׇ4~q*+; "`hև, P~)d;3.yCFX;9 `t*o9 Qb exz=0A  t ޴t^CHI]5cIQNNV#ifz~1\l$=UŽfFj=FtQUOm~붹R'fu:e-b\0go!K F2K-8i}jgj v(g}LÃX](űn6tWE  l0l![%5Gh uKco ^[S Y^'ѣKb%%[c(!$'#7vUk{["zNg u #%OI/A1F5^el]wĶJeMPUPeP,/&;)ͥ&]w>N|sn%i=[z D[_Wr|_ˎ7ab t+%fy9 PS^>6^^J2$_<ደ$*R ^8mP?++V[#mz q//Sqyv=M=ɳCH*]EBCRF&mA̴Gea#+%Flua=K+AtGP4CVcq Fa{9I&-!uH \}K"tڒ9^VCR旂V FnWNqrX_xHzg]iUgv\W%b.?[3.;>˷x>(VHbCS"˱F"y2[ǜ.# h9N\<%GT 1ҒMw4fm x9F>QɫN2 Æk^|"=D}suSue0"xxSM 5QiȈo* zsq [0`/*XS!v+c$y2;NP|ŌO816!C{kI{(hܬ'OdF:U-#|P԰_v65O][A6O#]? +KF8\}P"Pwg1u{y~\ w^ w瘭 |/Ӯ< }d/Il7AXBz~@ jaB ?ơjiE/QQ_ bkf, psj ֳ̂vܞ})+ZD*FI%I ?0b>7j$N;0tڒ'^%D1exg_KT$ aM28>X:u4ܔh[';g~e%yn'pY]DxhbT0m,VqŹڙh bd?t\8Z'qe}}(|kaש:CO"ttWn_~KV7u#Y5t<ME |ZӋ38}m7`A]:`b [3~*0m\ʼnwykEtc gmHkRSbM [a}0;叡rAy5.9wO8Nޙ:WFS#uza_mW C%!dp6"U 4tL=G_ܪh4jV|.]=*7p1*Z^}iO8㱶k]f6r%%FOiGPg!ǺdNy|排 <LG/n-%؏jv-c_;wF Q^?H':C?'9|{V` RPSUS"k֡o@\c@}7Bg_ק7ʴ]d*A(̫h'؇&xjJ=iL(%K[%˽ KboOʼnB8^5tY#m2g:Iͩd)K(C^O +C k0,C:$[k7g/5Y$UҜGdi=l#\{=jӞ$8HLďLcLzwncrޛGOӚܨ q\E;Y#R_9*y\{ۃ8gySRi 69 EjPnQ%f<>>׿ؗ1F_g }M9p+hiY+TcQ27Z-T 1ׯ6"q hsY,wS?Gm;Y돎{3SC'b ) 2EYqY4?KdIf`(^ 'a,sVVV66/zC&El]`Mw"W¡w+U>o+w_\g].?MzaOnp YT=KjM^?< x/I.뛗nFzMp :-OK/ x”l`~H#0|h%ݑkXq12v{0):25ҙhNV!TYkP v+Si9VO!Mrp(ZvZ޴khSb*[JαdA}zeWߛ޶A7HdZŭˤ ):sT&ݕ)FSW4Ey+=20n+yŕ!USBʲ ٵm2j‚[-y{Q(A^jW߸+a-|QI d;Y`ڜW-™0ڞw3D("1JYL^<(E[I^yc w ؆&!Q(0Vu1a%s.=zV~MsUDRuHC9lq͗{#}*C?7nM!F/iEݚMXVjE&Jo]c$}AffՂ뉇APv{?&_tz)g3Cҧ=(fnQ&!!D"FHГ -үxhrՉ3T8~SSZ`hߜ spa+!~Md+jt~uwVy0~LQSѵ%ڛiQS5P1זdDg_}1us&PHXQL%n`m3YH}8s$зƍ ;Oa4+<8>Zq:bB;HWf!rܮ-UB v7L׀v4}x9PP#ZThX^A#: ~GoEM!Z;@E~gf-fH)%l. )?I"YX;ڠ_FCP~UK#t+Ϙa*s~~ҳ~@CwFL+Jϊ͢h: :H/ξsh~)=\U7Xh=빗\룛>=#q-yLYn@zuޒbE$/Wi!L2JgЏ'qu\K1D:b_юR) y " VC"yQ\0E`-J1E_!~׬h1`O&R~3:AD"NJ*H>9YiN}Dl۬qqemE⚲!E68оBoC+6k_7",IJRF@= j#CAfU.S8L)2k. BWl7|}=l_ nK]$2:FߍVy$Kڒ$$`vjHE C(D_~vryGX=/L }x(%WzJJSD8r7ǁ_;"Zw5'-_THI=9#1'o8`^\P.M|ykyv+m}Ȧ-՟`G~%8&_NnR8&g+k&؃,M+zƭ?1'|Fǫv>>CX HiF6cuKdi;M%ަ]m!Ƨ+|I+4Tdi;Ut p*gcO͕*_Yn%=Q>⑫ǜ›ܹb`Fr@ԏa9pNkcX>u 3u5Z׵Z~Z8Zز>! D7dcdU峏l 58j 2J.n wȜƔ<#|} A'"6UY$i_vX_wE>VEENH8f!NB1?{Ek4)'IA'h_]徠w;EJq|_nAnTEKucUFOȝՆG{) |n#BP[:>kG*Bykq\5,AGHHS/m~pc=Bms'.knL[S3Ch{w@[urwQh 8Fnd$Jcm?[Cę'%E6,{bqlTz}(Fj1ۇO]%tjsK^>c8h-PѹZJ<,饠(ɓ*R吥o=c4pdǜ7R$C" ;endstream endobj 233 0 obj << /Filter /FlateDecode /Length1 1555 /Length2 2907 /Length3 0 /Length 3879 >> stream xڍT 4}߶J<5b)k]dɚ{m XRSRb%=%[$dRRQd_B&;}Ϝ33o~_FAOM2Z8:1 Ba22 #d4:Dh0X,32`C*d*BB ӐJQ,1 "/ SК? ~pF 8Pq#B"T~t*GOA D@,Qaj*(F @ vaR ր?Hal@ XiVA ,;cq8?Q|D[SkF0C RKX2 c ,L X ?:3*tn oD) :b>c྇ WKP(a? K4L `+6[2u GU0GD.%p %1!<̟``8DD  [!h7QbA; ^?4Zw0(6u ~Z0P|ȿ M`o1p98:vT:h_:p$MZVEфN`i4lF]C7W@P م* 4R={I*@WA $j HhCWAM§pdUE_5$7U/?4,,'ܘx `xӎ-\h=HyqZmt?f: j{1׾\Q$7/_T?][31CVwyR>SfR |6j#[?w8'WNeWȞ= Ҫ ڞW[L$0ЌQk|}]z{qFٴ1: Q+@@b|let7]|(qlU66\_GÔqU6}aS^iW~Ei9NOTёB 8X(dV!O3 2ٖfJ6}ptMیg}<ޮ)(”YLbừ.%m1:EL[/iR)A*߂}P]aR6]:YsvsEYZym277JŨib}[p@rʆעE-f7WNqKZ . S] x"ҹ.bhoP-#f>mkV(qKG|0?MبQ(孟"74[^N+'*CL4Rt,͑MZnRolY7\m33]̵/E5#ʎZ- Jy8vW$%(:iEݤt۷xot "N.eRFH IGE7WdhY_)j2L1-3˔IoUS6Fvoґn>14Sd\nhQuv bC-=]mutM@Lwх셽,Nc]s1 kNq^Fv @"nxO!6\s9WrBޥqmt3CMS5ĕ]Q'Ewmu*(IC"}[E/嚓2UV3IaǕG䩚F{d .9^dؕ?}ucQΚMHPw2@ve۳eW/e G ErQA; L'!- ,xx4%ŵ(s-`Vy8HݩfZº'a/Fv ?)f g^NwLxJ9IS^\6>//.`k"Z&۵*7Eqt-܉9WWLg&\pMc*;yۇalu7GAo Ѿ3$3{)G6'/ycp{U,XzЧ "=].Ew2sh{J]k`~e:cN* rֵ7:H d /O~Cc;~KW1”xM٤$OpW\wˈPZoۀ3"WmX[lϱP}oGL'M>; Cֱ۬fzdY;c7]jaY1V]#! 5+VZG,2>>) uJWİ#%;pf㛂Qnpi|dVNo QdIm M}KV 2"TE^+l֓HSq ݎ#"!w#ߘ.'̓K_߼%b@Խ,OO]UL )/->r܎s&3wi҈ȝc߭rLNhI-`Y^Kp*W)QmMS4ŽȩsO Vs>p3\bᚧu f('/JxjȘN2zj|Xpl>]0}yR.^zށ'Ip{j\QD08Y՟뚭S7dPfA57ú#꘳ն-oκ{Yؼi)G4n.*^;{cr*mkGQBI%KwnTVH>7P;1D7D9J%+ltI ݋HqEmU"qNZIVUjeuت ('i}"-֪yrC^M>Y~ԦX3DBFٽ_ [yRqpCy7&`}TRǁyQV|0eݑ(ȥ}cb7> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~endstream endobj 235 0 obj << /Filter /FlateDecode /Length1 1708 /Length2 9763 /Length3 0 /Length 10865 >> stream xڍT6LH4 0tJ#H 0t)]Hw-!!]! %!ć{ι5k̳L-kd ~sյ@ȏ̬ qc3.'0Ar};*nPOXODb!:! w5@`3;[;ׇ0 `bpau# V @jv|ht `Wr&i 98!lعW;6p[~ 9kqSdB( sypYe5& ' xvoG ++'G8l P0@+MA]A d@#s sB@.<.yyxeE#;?l^v @`6v n`e("d`W`O+;u?|"~  pE|oX,?`?CO aߟ> *pY:99'O _ &* ?Z _q qY aw Q@!a7&zfCQ!PN_MV[CW zY-g _-uC2G_j~/_!8_!aBy]^_=7Zc@F{eF*lP/l2t>ߚ0>&h{c=݂=Ix7>,jn][g_fg7Q|<J}K#/v*UqnJ'^O3Zfΐ3r`rxL_"S;(1^㏹^IDaLNzA42#B6SRIy6潭wj<.FA΋J&jbt̓/*ʧ"͖.\ {MH6vuv.i!GiR-G(9?<v&l2I}"MsmFG޲.A*ޓ{PstQkG 3$Up8<ͤq!LF͘,P3`nZ =rgx&I^leyhasؘFQ'JVUcB ʻFώM󹁒<:rзYqjS1BTfbu=$wŪ9|aDKgV)~9IR<%׼c5;| 2ҺpmzDz +-_~_xQJ)h;# Hvu(iP+c$ j*1@;Wg:x!e(*=Hdjo.:B6%=Xr\4g(Z= xOy~N$9u~5e(ɧ̨i\;֭g+zĄܓ_xَZe재כ,>pY;ѐGi_h`|8N[-V2I9n>CUqR RDtKx$]׸w=宀2E/+zHtU!e})szTn/dOz p,[T3aXj{!$MgծY+ޕeOث{{PkRoRS0/i՟q3?&ϕ;dZp a鯼w}?zV6Ujeٳޕb| IыyzuM.tA {ҤwtJ2lXBȚ̽F8iU^֓c$i-6*s$2 .}C5izhQ‡ ~[b%^Dͨ9$"fY/T$>Xakt8[V,*X[MO +X*N^OKF3_XGKgwmefhw<8WICDÓsw4#5 h^1(}}{벆SRbE/)1PւH"nqɈ# %PYdMڱ?Lnrz&H!T TO 4kϝʎ`iGlxF߬ Qisbd똏lCGd>NWd[0r}#=#V$bZl[Y-I"ySOnՓq=J!D 'lBRFGwґEJmܡjsRe$lt3`$x!Js$`K'ъc]:5J~v)N~ 3ey$R,z)O.$Q\wR&TT6)`SL] 6~A2#LsR,׶'/RIHr<ƘVZؒqv6 Z+3W' Չ!Cd+U+ 1Ms]UCͅIX)}bV4@XH{ۤM@V^E !%tPѥNc"ʱsw+)ܰ a,TFa;CKl n#089y~CsvTc X{Hp;?jyƣ>C~]"MLv%6TI߬$fa:H'E'BQWn% ]ﲔnOg{We*9uL3_k?. 57#hPTO 5B3x-+4X)S.u l~?ݫ(ӴWHMm2+&sϞ`Uvtm`"' kXS7 S^Ѹp޴{O+R\qD:!srgJ^ZǻZ̉o<;;=seo8wcd!)"Y7NZ#j| oq6'eNM9"/`>zߣXf^R}ǧ&WU6NĨU\yvNF$ ƫ)0mvJ]{XDy٢r1Б#QÓ ̭y5oixmvGE BF\6"Y]R66[Mk%/Ŋ81h>@|3-xtΤ,( Vg/ p[ ,0=,Ww_ا[5[!lHk3I [/Ĥ8M;]uߔ\n)B "@ TS0n;/7aV7}|;c۸(aѥO;n}6m>`DҨ%]R%kYUawzX|*M< Olyy/f)Zt%{집}>06]DGYZ!]}@ ?r3E]bAGm$VQ7B8𭏞f#a`%R'ŀGj}7% ;o/q^(+^,Ӏf(qvbo_%S:?y̝Z@z2%QޏslhY"1>zWFnP C^H6jr@Mm7p1ٍԶR8N7u֧J.{oh/V9wbF d9C$`=pbzTrz9,oTp %0Hv 4dލ{md6'a- f什L%zHn*J)?뾌;lՒ1_\dN~x%|Ŝ 1˷~= p\ZrϨ6 .ޏ?"Qgu6|c} _(Dž]rHJYPg}S-%OqU4ZMέ` `FIx]'K+QшWѐyݥMeUJUA7d+2LG91*X(PSau`ëL8C*GXc:/WLzhW;l{Zq{θ&?!R p'XU&űMP'z&@Sb\;d H+~-f5yZ٬GTxWA*d1ϵ;}b?!z1d zo :eN0 ~>*͠m7]wnS_Y}҆c5?XckŢdJШ;GǶ:|lY2_~^.$Lz+/PE&$"v g9c[rm߫Vlv٘Ql~7;Ot3uqS2ʫ-Q>wីǤi ؟$$]4FVir]2{ F6Fx]2V#z㽚Ijco +GyP<<1]LaH?jqpDXߐBVމZ+i׽c\3?cGɻ4 򆛆sړ>}R(zCipak?^ilK~b|m-wnh;d_\_ɟ v:G0S=H{Hȩ\CNZ1Q\3E|{ar,w vbʛm-rfSXM׀ױۛPVY\"z:pƚ{g$,_KҢfq1 @Sez?:60\4|U_Nln ̝{9:xOtsQ=WIz,(ؾ83gռ~տ[}sqcp] >ǔCCP2(AuȎ t^IYh:oFXC]YأDȴ{;}mEV^BxGڷ/թԤzԺp>`K U$8Hll z ?^5*ёe)4Z򫣀#8ss?W!KͲ)0ڤ9^)SݨAT7b|ZňʆsS] 7`zקUqg0*eʠIhLt4ntO:gu//6wkܕ/wPqPs_e"+TOr钜g'Րf ~UʞY"ipH^0!UrUr{H; $6ZYPQ1bV/pVp6Jn/CІ:H&#yU`IcOe梠^޹ ޞOg!}Lh"%e"Bѯ} Ad{+,AO®alp9,.& 2X?眖OS/wKxKm'?mmg6ؖ0=#4ʖ>Ui;u)h/08daz\B+Q0˺_ ?pwwNA_=(: yɠyF:}?(. V]җOɉjt3~gl;YkS% Y;I@d\yq.c.tO/)J} ߍ}>vpT{SP#bОZn%.b8gi!>/cZmsk2D*ojjc5eғd&ar+#P~%K<%H4g@5Xdtݱ s|$dp&(MAI:K<%G+>譿b?'+;]^?oL0f8~ MX|$|'G9,b,s2E&.PB>_? |Fgr!.9O+l#LJ>G{! yRB2%F6J6M~ͩƀRIXAub6F['-4F[%QW\Wv$s-)_!fѤe=ow|>cدW2j_iXtY"WkCE诉-q3F0bXv[ i(_>cvM?E@w"Nc@~/dZhsD !.n<}'dM=D,h^MR\˘&a>e(ܟw U?Or2Vj.n\Sb)8P gWlӜGu]4T4uxf= AK;rZaSO#;zyf y f[ܬO!NA`N "9nk_RfDu$h1\TKfOc6dc}nI/}k-_k(bE6{8Wp1n++~mV0.8v eqʈԠπ7Q =Ok3 ,Fps#DBVbKQ7{y-jװjIq4'xw;گ7/ (Hj/\b?CdzO3']*8dg%nW4,aN,c}*sW2 zo-ɏDqzHu.{ J>`p]g lAyËmUtPG[ϐޏ_+ɣmWo4⏩yW*ZJ5< d[XXQ{G`"W8O5yMB= 7weC؍S٨oEbGBmKRw;UV:b*9sEwMn2ҋjDq5O1C8?V5 [:tXxhu6Tk~Н( Ȟso^"莕Q \gMM +I"9\%ˍs{*4c*2I",ڬSQP5J:%)n"#D{\p]nI&yi_Ĝ' [M[ݯ&_RV7Oٽ&ģ9F|\PZdjD#]WFm,f:JUfܡ]U=sE-/ћyIF1L$hذO"<.M=C=mJ;ִZ`K M =Z6\.8@IPk0Y}HTdJ.d$Um{|_.mQHvk찉TQ*[y@Ğx<5۳^U7)-i#$U16 ١}Q]^=9:$\y) _s!c额L}m5]SpC?Qأ5A5IgU,|k(P Qkr/g mi"|!]C[4dO3>k )Ng < rְ'ЏED۬. >DSSh ir?2 "FPǢt /2ڷ-}~[3G01Y.IeG}Cg)n< ?oʸiCsVT|rUr'vY}e;$s^]sB|ӌOh}~>} endstream endobj 236 0 obj << /Filter /FlateDecode /Length1 1579 /Length2 8729 /Length3 0 /Length 9761 >> stream xڍP\M-kp%. 2E`!$; .%,%ޚ3gm^:l6P+Hjq@nv ^ӌFrsC!B vYzmAOh^ '(ߎ"4NN `Cd 0>iI^6P?ϗCFAPWIIA}l6.^ @#oUހTBPx_4Tӟ j')L( ~zp?wU)7$q[:| xRTBf?&Ydt_tHBn#]{X!N᩼Ҁ56N |Oft?oi,jkxnnh'yq9[v)D/` uCu||_߈ p#^5iY84p 8@N _Osp >-// S)?ts{1~kmF[Z G8F$fOgf_rDNezv):ԋ-t!LuRݚvpg5ۆ8I?Q/YGJΦ#%5@/K>SS'yϣQ_ʦ^&[e yQ`^\NG U` vYG_c5ܿ ;T?Z~rX@gZ¶E ej Z Cn3NX3 Pq~M*WM㮱DĆ0qp$㭱3LLH׉G^vԋ.zO(0J.2z-/dml ܉dP'}R5[SɱB_co<@*mBp!g7h"qe#$^$~\iby5T7D1:4 \M^ŇM1fے7@WRuH.w9ԭ =/ʇX;F^  =xmANNXN;T"C!t|߱GW"'ߖDUsB1 hy_ZSLN] LѴhfdyAPkٖBO|✼d&VbaP[jwNZvȑq,SX8dk>3M+:1˝55S ua^b$ͧn]LzBVm] f*<}#*GCX)#J)z]iQ/+T|3 x}EFڣ8R<"Q^!?9r3~,[nu,)x)i[Y: E}ր컣Ȕo xR5WqcRxZ$.mH8{][]K2qks,c,}K'=>Ν9n{:$ZRϼp^Zͮe{?{@otKrvRmK*v*irV"Y]̂6 GFwiɐLJ`.U$*W#Wf }4s\Ζ A2F+&ddX,?Cv9gؿ- Lg&+ZxAzs)$qvWxG@4dG@H.#MO;6k|UY 4EwyQjz砨ڀCgO.tfnQ6M|x9`#7TkQJյ5h+Ukm"/f<Д5NRDOQ6o1C'2׮GbScُ?U_jwV+gK.aRDqW^RACuJsЛi)޲ k9u|۪VA2!j >4!r 4^Ϛ'4i|J=C TJzaTbSs*Ӊm19>r0]#[Rّ[ NS;BHMN'>" mmWսRxɰCMwFnt`V. IwQpl= gh aܰt_8Y[R9R 4а%M\D\ D&K!>WJ䦰lM2Ǎ(\KC_ґNղ;|/e*EP42|hSx޳N4ctHeL ŸhIӼQk:gݶ֣2тmR(3W҉WtYPnWևBtBIVj[]e#+_aj V Y^p˹-Te\쬝R80`E[)CɛnC5T/t/1J]||)=}]#2v!*qV)0u bv,TGM H1tJz P*\p v+Wk*&YDʥ}Q)f)ܳJ꧙/G6wA K}iN}sE"UזIW>U13JāfxI;~9`u?!"8lT>o1XqSJS>T6"ãH֋}KC"( x%ݦ]zU0b"~.Me{ &{K(M1mP-? ˮR i+էمM8&Pˊs4bz jsk/VԱ XZUȻy*(YV5vnV;m3) 2&qMrKƳg1DsSH -jABd)lDDU7]xZXo<ƕ~;hfOZDT¯TՋC$fZhOw?^}r6h 0@\I   , &{ p'IӀ{J{>$!}8fc+-rX s ДObMF?*8؍a9K,!i:D> TI"2IbRp']7Mg>Rۏλ/MEY&( _iqnƑx}nIAtTfB/2 ,iB e%Ӿ<+e,%?Seger@gNQ,ˏwU5=^h_4#gmx!ihm~GW?9 +zшey1:Rj9zNCYڟuPY4-k  qB@'d9?e- Ŋ}"]F>{֎"#63K7" 7|y|O݄)Ds7kϒ8@VgsS mrQ￈zV`U #҄j^ENRBj$ %&8ʁ1?ϞG\U]AZLs_kgiyEmOa<8J$I=53p'yn A9I~fFUPЮEm˛eLJ/$'{E(-N ;mC9bϰbk!B93Gp3YU㘾TڴSM!چB A" }L?n 䢩9 ݍg6 fqH]Zd5p,%tع(EH_IƿCESӎ<#`i-EED"%TsпdJt-4(/qMGS-+qbZ֚ !X@#HNrvJsxJ9E:bQd BTnic=@W* G_ĦY xX4]i-ġDט.NɞײSTQhQIQm#E`^sQꄓ0_|KuyPVFY}B?+S B؀dݾك}P`ؓYCxcQFQ;n( U,L|vr2b*-^Ob^%37a,-Yr{/r&0L}XYub'o܏!փ?Of&ĵvaov+ɥ^Zbי)z>dv3Q6l ]_#H[CXFdvY/b}r>*J^n_ e1FD쇈u0 }(dξ5 1\P7mO/Q&/WEj4\BF_᪉v0飲:X_L7}~Q15<*:BD2MC >rD/8 OL:94fa.gMŻFmXP .z(Gũ^ڗz4Rr|'sͷ%k0EkQh@czh^ycNAq4$ZnZ(f_D OMSw=~V:)w}*E]MMEYGdg9'hwҨ]J ugik_FHFܯѽՐH?"D\ܟ|}1P-UbU76Iض\nXt&l FgGB+|qK>= A0p%d} M[ +:ٮ$ 7T󐿭[ΆQHjjwo`fSdBxt {t)\v$Zfn1YR$-5|T'Ap@_ei\L'ݲgU/8)B9*le9WwIn/oP`iy>I ڛ/f>z_U,Xqy~.5?4A72鸕҄uΦ!b9L _쯽\5LSTROUԲ#CUP[aHrCi)^P jߛ UAdA.*@ Q̕qGl c%ݵ'&%b[>%%HR)cȶ&L_:Ei6.CNXoD?Q*TiT4K=n(MglL/7=@Rm{oDbp4USX=;+2LT(V;(^!'aOCsNLa7!?0z:k#yoPKjH&xS}M\i3[ƒm~ud#^q1x+at#g_|ˆs1άRIϔځbC, <ӗmLJKBvYu/{q71QHT@|Z7~r-uv+UjH}ʋZtPFNLLdX?(Ì1{٭_j0_&i mAW IݩU9YC%1(8ڠ,Y͘8Ѷs,“+ <70(S?yNS=/vO,|F@[t ,&TH 'wzA|/%~˂Rircԏ ZZ8(+n{1 e1mãGXp҇z! Innjn7Q7?zÿIt!K5+Kv>_-3EC R_1_ŗr',J+~.]sq>BJ)*BL΀FJBT6ִf$nB'y<#K ͆ŹͶ4Z͢w/ŒLi:W b(J\;YW%40NF89\E=ȃAkf!I>ٙVHKڝ>q-~(GŨÓ+[FcCZ&;'ҽO2> stream xڍVT￧$F42 ݝRcl0`l# " "%!J9y|W; A%!R`% VH+@!1h¡xM 'c@ DW((@i0X@ V  @4cxb@( ;c0(h {QĎ0C*!rU("* D=pw 4࿁IVHfK DG hw8H 7 j)U 0(_(:">p>/B}pb>4~ Q7BDax !W%k51(~O È =Vo4&Mc@ H?֟D ` y~ vB~#b|"x'8h#axSh#'Eă~rǠ} =\o440A@PRZ @ Eؿ/쿭fPgSQ@` ?" w p?wˁaM)U?h^( bH4 Cz%!`Zy_%8~D)6q9i9y 'Q߼<1HD`_pDcD<_ʆÃ0(v׫[o*y%lJƱ G T/2#gݭLS"{j7bCO\,cWvJZ-&Cd , ]7tC yCړҏwo =KQl1d$L?5s q9p|DXM3D(.v/j&q ]QLR&nlDSdr+'LQRWM'O4^?: a x[Yyr 6D.WZh=9uG,yG$K"%`!ǪBבB,a\VuBb)9QfJ<۳d4paofDjģ?caѪ}#ɢYi#wY iz-ǧnux^ڽoBO&֫ZEyJ9eɶӘt:[ 'wXaΈ<]'+tP~qR1Xb/;kkdksFUv(zk6 NdsmYUe]GZlc2̩5,tYAsu&~f'@x>.{*p gQ9Y ֠uÓ[&='*f>P*15 &bFfFS] >pr= BwDyuZeBS{Vx1U!X[?qJy-YDع$m\!Zǎ":.D9^{`Nי+#.t9=y#C njP/{ ^dnш; P| h / ]߰R'n:)UшJЄfkiӚ ET!/tlcc)"仃ooUAq*~-iORWJSioleO/i?,&HVEt^VιYөop@8}#+r#!4#e 52ٽa{b7T?]L{MX}uBc`Zذ)*?fXQ|nʳp|+5gCr?ʟ h\ae:]^ި6k3#c,!he3M ]*u8@^S@-Okz'mʥ[g7K=2e}d69UK~Aw)(KN0ot8 \}pս)kJȳJuDrm'_j.ƽK=P\/{ZC[*QHZș4PC;[ʑHeЖ7~j+'cARrɴ)+}I'2 zqxCDNCѵdB*1fdj?Iڜoz">H|8K #㘛YľRW_&/-_RnRyC̪x/QKޏ]Bry.f27eO.;jsUbgdgn7ig1*RBOKRuGeRiA}懜C =qN7":Vl$x)@]$ CE<7VxL'e{jXݎlB{>臵G5*"#Jb^φ=F. kTPBIIE҅K}} zGė%؅Ǟ)wPd)rt+b̓W7+jF(0a qXqxJWǫYg&ŕ+JmY(msdvBr|Q +՟emJ^o ÎT͉j>u¿w[x<|XYϖV]#f+Nwt\.'J$^_gF}eY9qL=rJvփ@x2YA-2[--=衡M'[Yqk;:{Sn: 40rOjR?=wrp 4.nݹ͑@+1#8p0N|uM/"]J܅N=-W'lF3SXti2EQ ,X)~"2^>9pZa]WQ*S A s+0ףե5U7߶X2WZ<\%«IiјVWvndw?Y?9Ɇ'j!kzvmg0K݋ڬw+drPܸp-d95EHamA#Aj4*|شU\ζFa{5|${34S19wPl*l-OC]ѷpB4w'uPCxn aN,ja(W[xX f'Jm1܈#։0yNB2E}9]Byp>4' tFYVSOjhKmڟ"uP^{C)/2c.f[OKE>]ҋfx[.pGfxB{z!QqH-ƃLМyF[ݭ*6mo^+H F?o~R`[fO5ز~yGWdoK~df${.Vv[HPèFٱ\ Ǧ̽ҖqNhc4 _|%z床t e鈪ߌW==rY0,:W#IU$Sҳqk ek ŘdW矸b:-{!T^T|F?\G{K ^zjsB mHE>6y^vX%wRP.2xV4ģX۹j4w2mh M sL}9EWVŮ1(;x(.ݹvu ABu"zir2|,s k\9"ftFՅ/*TT<lKSplmrhY|etL3ɼPR Б6YGrA8vYUzNZ4W43Mys0xv735cmEf{=gڌXETdo$!g@TiFk_P%[m/֞5os4+8[c:6IwcB M8E:dдuj:s'vpJK@f.Xli_9i7%]08eaH3#Ĵ*Mi9 :zh\UcN Ҽ%$P^%ZBu˵(f*@VswSJКxpriMz^qR†Sygl'&:K3Xc+L\z ɪz V®Fgm'\;Zi#ҫ|v1P{NA~NuIYh"ѷ暵X;DOgmr=]E=#[ /_M}ĥHn*+SR(R_tsQ)C_($G]`e\thl$}ۛne#>w4n|d`!:K/Vh ܗHuZKC*fzDe܋gZt(׷ol7dFFy8!fz9=~Tkc$Bpb.W+Aw<'ٷ8PP3W{NTaY~$}vod/b"e/)u?>ߔ쥉W~X\%@p8rgZ$'{[hFs,IM/&ɺӃ+C]U;+eiM HlVyֻ5&_DKxZfiPn1tK{>sJ(2\fҞOkv&';WцF7[X\$B"_glq{u |nwLn`G õԸhPii2 ȿYHl]2)+ZpL.b'PG}ЩXz@X/ջ2nf~pz5! iOuz;۽ABJA[s4G3sXg궽;,O{?Oi3Oⵒwv^5K`$.V\~Y|gaRMy]3WXĵmMPtȐ8@J.@'P_E=gƦ=! 1V2ᕗۛ^K`ĵ+l郣c{ߚkEq~ 1|x[BQm뻏9i])m$Wjte}sdY74lPpLs7Yf_| doBpt٭UbFuf.#l)4X=@Fp{׃>LQ.r*!\AY:z| \]tc8 +}z$PюUCy0J tTEp?.,1qur\ mlL.A\?2.5%H_).o`^ NxVDAW(,F;Kư rrKF7BX7RƏM/8PJ;'-rRnJ]iR+\Qd/D4:2+'t4'س?q6$MnWwU;K_)' LǓ G -(l2ɛ|Q/u495C 'L%բo49Ʒl{λO4D qL0/34fSֻ9iS,BrŘ`c݂^TWx =ٸ;\"|z?H=HŵxS'S 66ο@Hėur=ߥ8'ş|Lvc6KY} a,;k*RFz" UZendstream endobj 238 0 obj << /Filter /FlateDecode /Length1 1621 /Length2 8829 /Length3 0 /Length 9878 >> stream xڍT[6LK7H H ]"] 3-]HwHtҝ|y9k}ߚ׾s3jpHY,A0(- Qpsd`!? W0 */ (?e7 ssxcsZje srol vH9\VPx^E,j; sqyxxpZ8r\lY`@ rqYHn'&@Xfp(4@?U4`U7_-`NP/0`pO8;jonXX> /x\\NpWNW0 y,Z]1Oz:@aP?6`)X9qAn %ٿ,ElAp77r< rV?s<ۀ0}\-AߊF@ lXlP ?c]#}2y-krԐf*ii'?<oظaTBXL0.,A8 ?com?o2[pC?Nq#`{_ӗ?X d vs_q3v{5p+??=x M+gY9<>%=_)Ys<|  /?">q9A ]l`.S@7zD A?He72{+G*Ji:~@ OJ}Z)Jqi,> .n7ORXj^\J /o1_H.|mi|֚v{g=ӆet`TC?3]]{g_ .e\g7A\|k>φй~ih㠒Yi*5" yVxU.> аY */ ٓ}ge)xz!=SH/0$,h,%ǟ`^ Pw}Lq)J% Ѿ۹2MHG,nˬ eA9jiT#-8V_T4p8 ::KF_/lNY=ψL%N? OD6|xyñ5ܾjءMMx!$,׊9oQfgNWuiKaB8?G>u&`wz+,Ȥ2f*b34?mm;B3ϓі0;$٩4fK_͡0\`H-)Y>%7]d*q`'&hT%tX҅ZlJ杧jkgTĴ0Ip"$p ʨA.5@=Q+vH¢~EqlweO<BH\G&_ix*`;c!7@{y2,J)x*jϖۓ8Q!V;"# E˝A~/߫q¾)g_l6wY5` ".Yۓ跷m/\" g Aӡ(ܘH+/ ~?,ANk\TuOev*,ms6{>]bk|%%-QW=r`e"7}km 3G5<5:Y{%T̾kB:c{YrәQuMOT.9$˘Ia.mr?MbiC1HDu-f氠A#}:6yӥi;H=F645 Mtι'}c6gbyޮ@O&9P_ԅF2mZ0f"S:LCt؃C:j&[iz$qor&ssQ]LL҂ g>#:"4+gr7D E*>B'ܤ*:-)kϟ_|K2kvS54r%hs NK[yT@eǧ%wWβb˨GBSBL8;¾>dcB x$<9:tȺ4l.бQO&Jq6|QÄ,9nr P5өɞ#>g`—t_=x0iaCz$ urIYN!IR4>ݡ]Tnw,qbuf lR9IGfeҾ #is.g'}ߌa5|f'7_ ”e?L<<{l~MޏJB45(I+9G:뛮@T5qn|whGfp '9ynC^kˀG_-?w"3_ `5aъ!>q ߁W/G_ ׋#+mXn깤dR\͹ܹ}<ڧ OA.P'SHv ^WzU\S|bpՙlGab Q%4.KM'C˝nIsdbjmፖ/\iṖVm23 ʹؼ8gF_|MF1bZ.>`rW~zgc t]K*E6IIm9g ~;a#[hv56"n瀩YG.#u9_SM8)~[FYҡORgЂ>jo앎H[r%B)3wR:@SU>[չ13#NIwX69"J:zR$җgfd&U1Vyz|0)pqQwnj6R]}Sq A5!K,eVȂj܎.T:kGzcQ\Yn7rvsm /aY%L mNj;R;4"J8~fSp7YV3Of͔/8Ժ'b_hѧFmǏH9 \:(JrUhO@_)9QxP)cBaEF WS9YHEȧvz5x:;* V9k^VY( 1"gW^0QyR'a%8Z=T u\t\Uة>}xߔze 9"NF`С(Ԧ̀pG <ㄎW)71:srt fi2@V5%xtbKK=UK+xFzc%~Fc2 p M|;ܯxׂq43v|(W2d UK:eaUčr h'N3V7tn.hQۣ% 6P`9|1~9r7ߺCo8˝NTS/q"zPt@)+qۍ_aTkRJQLq>Rzz;oϫh)^X_NELDv6rqték[:V|X5>0;)_SINw8jܳ7^|R֧g5f7-?S"8Jڦګ_Z$>B%/ {n) 7|7XR@5E>@Σt/MybT9/gژN6;+u-^O6+'WGAh:)L$Fs*B>c5LrO!ۗk+?m{#:x~ǣ|.@?6 5*M V9^1 -"N@1jЅظNDENSB-'۫g geQ$ӻ-^Ǵ"ܤ%e4R /oYcЖ$sŽ2B: ۴5F`xh.} ~%'8ia|~8BܲN^.DZ!WEm4"N6:t~8LJ{n_/InG4mIjait6=s1Lu_䌒cp_bXq=]U2"?C>xk;4fρ|z؈e]Au\iVnpHMY:9mpz5ӎV{e.VA33b}h3nēf, ]Z+])wcMIU鲣Gv>Ȅ4{,F7pd>y&oG6bDd3japȼKI2#2jy[ ~8hFB؇(c=XFzx%j8jZEV&$f;{ y#EZ̯u-j ` Fz=.(?A,Oc9]>T1왁K42LgDN7y`$.à{ҢAٌߢ Qݏ1K&jZ6*Kٻ䋞^<OuM5/;R%NGqAhL:?dchp\;ql(zu:.-0blۑwRm>_t,* Dϧ~׻\:.Fh;ES<&@FuK86" ;V]OL$fBt},BDt˚u2Zag/tN QQ9ot Nk00EbM]2"$/y;p|˦Ew|Xme}mA}[% 9t1•6FC`fbTEf"\JF2ԇ1}:|X@Hd;w\d1_␘ C{ D]0P_3ؼNŤLA=vuA+>Hj0{u%^bm2guH#bq|2-{iGE_ Ë4wdz7+M7u~IOYo,Ʈ=L 4] ] }!osKB{F^+HyAA΅ Aysz%Ut0WJsh'{|TM&',[B oo'E:Czp_"'&c@=dvI7BD!``vm%$Ȃ4ԇG_߄ޠ-?ӟkH^+E?&:e3WݾGf'^SftX+"f;v_L{k@yJB(^Cdˏw1 dFW$mY_'Spgy$: U>qleaN9 .yf(:r~{j|&r7ayXը_2ksV桀o-[/>A/c%E9&gz:Ȝxe +LkIu#ۀ,B!m=2|YʔM.ӯʓ;a6,=l`ӑ*+"+j ʅr h{i_*b({֚6zus %䙒7i"K:N|YT;k>.7T&?RzǦF[,g͛3K ketFʍ#=Ӽo?8P`L%kj 8yf/h=4io(8!%;(Ӹ&ܭvDY 5;)eTѪ~ݱѬ]^'u C3F\#iˊP2Z1Xf95[hZm QqXj/O~PxИh$!3ˮJN#0 ӽwe=N{d̟xMi&1} rw+01q5ܧ*= F<3?3@($$3v%p R ZQ"FXۉ٭xCǤڿ/eMB4VgmK@S崕WR4(K K2V!D'EߏR$d$uEt{w/QwNȨ*ܶ-;Kf_e/r`'vRnTRg`rf ^Ii}B{/hS;z$i1~ꊣh W_%Ϋfdi_H+u4x|3wJmhE<+ <;lY;QQ. MƁAqYui؅N&mE&̿<@rKqDb΅6W?ۣ#IZ 2MY":Jp򺖸w\ iS@T~_m*(F p{ Dsji.n}}O~R'/`PS?!L#tz~mUH6,(.`V8㵨ڴE?ՙCoSN;Uk̢l>.d ;lYp\M"+ۗ[clt;#]d+¶W:d}Uz/$^{ !'|VA\c]]I!gBr-5A\Cqvok*ijyҕS+&ܰ<1Kﳗ}Ɓ.!\SJ`k2@3%'WvXï!Ӯ ȡ&Ik*&}|A`lO%jSpaHendstream endobj 239 0 obj << /Filter /FlateDecode /Length1 1399 /Length2 6085 /Length3 0 /Length 7047 >> stream xڍvTSk.ҫ4!${oR ! $"("(](MAQ{׺w333{m^.#SQe(BbE@<@UJIA q ^^38 QHPE XM QH,K˃eA 8$7AP>B0(wŗ (Ɉ(#`h# Ї`]`|EGaqJ!źˋy{{! v)(c]&0 ~@?̀38a CbH( j a?`?_gIWDp`# AHg 0b}" qà/ 9l E㈆c1@ E_i𧬎?58?v؟κ"QHNp$ 9 V 7QcsaR 9iiIqt 2Nx @`,^Q( p9ÑdǛaN>^{`xyAQH7?474?>OT *')@FV,7V#ItBP4R_#w^0?ʷI7d+K! O7n ApJB C-a&Y{"۫CW(Xcc4>0GG_ 0_|_>9?*|~`w]u# kĥ45&.% -oCx'W[%b 3/'ſ 8z|׿G9RLOB׆(y. /E&XuGHa>fjyC+M= gvCg ܬň09"D8FVP~@q) t}~Rb boHL`l%|~kд:ibKQ7l*}-jyàJ䌰E疗PQ*(W|r5a\RI*ZBZa+Y.^*h%9Y-;>G_MVmrQ6Y( %u EQӴ9aOT(%,wF{If"02kGY8H1̣,#mFP6yO=. z{ZDGYp;?->'@qa8bWb~rm c+7zR\[Z9upx}mS~&+n9K)HzZ=d"ݣ0O #fzUv؍e u jƞʾ丮VHhTM ,=H$d3~2pǧ: #ۗb(DjHnwh2~һHZV[9u}X=K5L0Pi !X~Pdܦe/J*<'`Y=͓I^f5X?*Ke88\>1RբMp;fac}\׺sƾ} }sL!Bqz} *u+uUsٳ$`wRnN:I R?Mbw^{) zNNSJPyd UӚk)#!|ږ-z])ᘔ\ϼl1H:٥rdEf5m&/ .S .i&y5)s~Aj#7\~c;;-qÞnlmk`b[q%Nk_z㜳71 M,[>iP 3@jR7uv<z/{N6gy4c1,UqR!R+ \ZP0DU%fdLLCsy ls?Aw}Q­G Ac}6畅UU?Ofx2mVӸ[AHmK$IJ>_wYyW!>a2R't,yWÒu_uW73yS  we[s`4njU)#̝O駖}7$X!2}a,dR%i fRpʼZSD/5-EԄ~d 9{۰^kvǭ0>46 gn] tN'۬א̕zr>%%e$v჌"qQg}/'iDmp=Li7roG0jL#\]Sy$_ uˤ~:QS *N5 Dd𔐸ȴ.9rAlH(=0H>ߜ0f#P7tmV5xnokb4,(kk}~(]{^r8¾0^7o|Yj/CeG{묫䓄c][r{ZrX,ݲ+hNgޱeX _H, Sn4F-T̬eC^ [fa;s+?SA H R2lD;W.- tU \{cnB셮c>"[\9a?KQg޻̻Ǐ>!&b~MDM11-V4K :;&`: 2UErhf 1yJ]m U( _rHJzWyeF2%ME,Z_~ZTp?F*s2U듢os|bV飭* \ݥbzPza ގX7e$UIPfY2Ao>̷"yZP^0~^lǪ_`ig.ֶciF:aiF%B#\`>^exYgCZ-|d$A{gdwέ4yąz_ǩef.4> Q\O+ ]3aJJ-/;;껛A.}d}>j҈\ [~'2tH%n^ޙ}6M>}'bҵUBtfU>alo|0eɝ$bN./~rKKXN/sAͿm˲hk׫|ˇHnϳO;im]+aԮjLK`/Mp#-)2GהdH*8[L:go]TgU@^[X@ʩ 'Z[ƇXMԯ;ղ;fiL¾}˼?fv& Hۧ>MAӪtwV|ߦuX}4<6ݡiW'Ρ}'2٪ɯMrrW^_qGC;9! ?LGV+/=„I2 P wȇIv[YW~j.J .)O &!zÕEk#j}aicXssѩs*׶}O4x_;*#mӉ:S8sSC*v$voy.e3w (_C̷gy3W.,c{Y!I'|lђ1'@o54 `zOF61ߖ%:!#&Xi`V 1JY4ǩP3˥yģ9kHn7$g5N;9U,\ltd+lQ6E&BZ<^yfT%rxDǛ]yֽhlyH@S_9"9,eQ$|DrAoڂ9 G;7rղ8.0; x 8mrhI[fer"NRVʛa)aӫC7 eT!v7?tmZp 2$|xSGtt]5,iTEl/MŽw5 9؉x.i_KW77£,j~`\EoL 1M _ ^)Z:7ԎJmҽ$ 픟ZJ9e$ ,qִJI(t P2C%H /M\ez'$,zJ$7L7nPsG`AQ}#C r?v9GYb:VQU޳u.D ޷+Z^Ϸ:Oքئ63*_S&[hvh%oakџQ- m*ؘs9^[7bmSʳߝwd+؀)cMIIOzʱ&5lz5uH}mi1_+τަoϤf{҂ޑzcn>:lB㠵Kknk #>J>|~#@ x93l0N RR8YɌra)MBIrFvmvɼ"o͔4s?pZ1=:_ʢ'10iqo9|sllLxT*գs&P8ԡVendstream endobj 240 0 obj << /Filter /FlateDecode /Length1 1400 /Length2 6060 /Length3 0 /Length 7014 >> stream xڍuT6-N etn;Ac0bm4Hw4JH <"! t{}y߳su eD!B 9 PDD$""2C`]. 8@!Wl,.zEŁRrr""@1ٿQh9: ($RCNX\P>tB@ MQP NX7Ў|@o h^p'`72 h43"p$ቄ@\s>;@g6@QY BQn/t@ VA~B\1(\> p~T1Bp@w,A( nH b?硫@á ެ sp@ a?A<݅͑O JJII@Igy3_w/O3A;D8q? Ģ=@TC@@{# : w}-EpG/ O kV?>UU_H\($+) JK]?/r"TA:17?#>;A C}I(K[RoYE/7/ᆸ!\}C-ῥl!<۫䡂tQ\HT$"ێh"|0#H0o\p*~8QTFC|"8X/) @aťq(4ZŁ 3ۂO'_ h4N~xp80=ʇ; o>VadskLUw${򩿓lQFS#G>6!sOxK[B}ǻ[0tFՏ7)<,'";W+W[1ֲ߀nloqVll(LO3s8Djs<81ܞ *HFZ?]^F ^K"F] B>GX ;JGdph~w]Ν&NWf{OpԪs%Ar\=pcKUV_N tÜն.Ie!Ck vJ)or޿Hb$eKG R2I}Ne:Pj3f<& Q8N˓xH-e#gymc>*~tQQ08q wLJaF]⬎g0t^d[rRmWd#>uY[%7u$iPO)Bug/0GKcvNH- ì]0cnjR>uhGՐml.A0pƍ.[[:0n`#ӏJV_HSAtC̕$ Cc}DbR#,ELըrylQTK@y7,K5/@uYRC &!U[ݶ^izZLʃSS#5VO9{f*vMBz ~Zj7”ų?Րz/ڻıQgԙܭ[^x' _hG5-boVq'pyjOcUȶd{hV piÈeDϱA PNBb1*,BΓD zUh W&˽mo;3b2J",} 'ٚD\HFcβ6OR=>X>{D@~īo-tr[2Ye\]+o^k4?0=lܮ eN~ϻD(et[̵%vǝ^Ly*όVXStNm0tlWڦ/=2ݨcĭ˦ yxc[L 9gzt;Fp&Trlqr1p󪹗]0'~Z F!T:5wʈf09 rw8 ﭸ |8v1kPaԶuJyM5ozwoJ#6&c ơ~9ԝ$d`g&li{"=Pc. =B RװW)uN]_}:jD7<MJmx7䳾=e*F+ŧA>]D7 2 ?V"aW^< ./3uziCsۀ*v9&5[4%wZ=7&b@l #Pwd H`|~؝ٍ]4#lۅq)miWDIUC/s+#5IlM3̗az0dَk{CsI辶4V<I-sH?'>[4.'$^7U,s X*E%q?X{3NJf'EG6|R\XPqRZt gngJ`%'ySm*?5!N .3 BVQ"|N O^x)>+]pAN+F e}>T 3;_{n9 ge{fcb!($:ȾI%׆}ZV#56Ot2!kz\ݞR`BG*'AZMGbDn^k=W*<"5Y]Vm~Ջgrn1̠qh y%I*m泉ÜjuOJ3zq6-v1샋Gl.#Aކliښ/OkT& ׫|3PG(V_lGGO$iX1p NνToޕ~9ϫۅL.li%}ۀaU% zc#aϔ(v{ mz(xuܽI8­Pƭ兘)d!=+3thԫlSVx$lgI96z Xrù{ ;c(&_h^Ԟmq%`qP&!FOzu``P}ƚ eԸLzY :w_$%{PFx638뿏h.(w8w G3=_o+xv~~` 3'7y=I6K%Ys  =;ĦAu(P0rzX9B` "@awG[U E8*[n$;Rd )ݯz}2ݮG+ūssZu޷7_MQdٺ{|$zGqI:B=g]f! %׮vp:$I\ ʓa./tY1ޛv,WX4]bJ.| 2])^Ƥt)>Q:ckM̓s&=JVڼ]}mp?e"/HH4#l攻A6\tl0Е&4C֥S 93%)`Φ m{SCq-V]k1co[|۲0b*VCv ^۵G1猪Kխݳ[ amF){FNj !:џUpvAm#mY@zm/ZLDPƧ[&7\B\Е F3ǟ<ߡz8lg(N?)ͯtxH?C+1t/0zZqUcblw# 6ש\ Lpz)\f~撌vkA(ε%|g'JU:ͷҚ8 ٔMC(*f]z";Ś~XX.$9ܔ{EJ7cXCϨ>:+Hj"; EØ}Xx{{HMΘ`z/}]p9@dN}qbᕨaIcF_*50k9P-e5Ϫ%u*C?4 `E*o͑_ʪNp8ؙ-3e;h^Sut5M7v#wNoO;I]{W*<7˞FnkTǭ u%nόx&N,ym7J>PblbWȪ@$G B}oZ._drBr`xq5w1J 5"Q[y:w{_^tOؘd*g1^&S%Zl]qFC P+g DS^F֐ P#]i~w_P`₦C`N*_f MT`WUwI)maGԽ|s#njd0/k1K ^cɬ ȼ:|0r Z ]m=%C)T8\ﺂ1-H)n.Su`I鬎W}rTWlPx~f^`u+6,n0sH Ը)5ay0:6ZSU-/苂@F>o n/;{M?'}^uH7/iyK_k=9',*{|!XᘋyGPrƹU7yzItݣtTR:%+^ OFB5GOlT(<_l%*Dl *FI+||>=7w ƅ W2[Nݺg kiD}ޤZ<*X!۹-ee~,@;4':`G¹1alm-r| \u\Nh*EҼ gk-odNڸcx )i Fϵ*)m%v/}8-˚GeJWvb㽇ʌXiy79HkKzghJĽxvUzZ$X*@Eڭfv[nƱql ZTF!EXg Ӿ˹AdG5YsSK}f5`2/0C3%4g|g#d䦝s 3ہ:/5ḃ\Ūg.^ NLPM He皸?uv\s8 dY(\ۛLЦ:OKHµ2w^g.4iU$Še j@B^$zW?D9cYd\Eu`(h[Jk#;SR\%W+OHƅuK9(20Ѐ*PdQx c(~ W!F*e?n&M eݟendstream endobj 241 0 obj << /Type /XRef /Length 189 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 98 0 R /Root 97 0 R /Size 242 /ID [<6e538e9336a63e7c0c214500c0c69b1a>] >> stream xcb&F~0 $8Jdٜjh%OKJ lTS "RA$q "  xc)! g5+$κR+D2AtB0&0 E RIDZH ѯAC:3؅df ~ "'HV0D6' endstream endobj startxref 386235 %%EOF hexbin/tests/0000755000175100001440000000000012371752266012722 5ustar hornikusershexbin/tests/hdiffplot.Rout.save0000644000175100001440000001273612133705212016503 0ustar hornikusers R Under development (unstable) (2013-01-29 r61780) -- "Unsuffered Consequences" Copyright (C) 2013 The R Foundation for Statistical Computing ISBN 3-900051-07-0 R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) Loading required package: grid Loading required package: lattice > > if(R.version$major != "1" || as.numeric(R.version$minor) >= 7) + RNGversion("1.6") Warning message: In RNGkind("Marsaglia-Multicarry", "Buggy Kinderman-Ramage") : buggy version of Kinderman-Ramage generator used > set.seed(213) > x1 <- rnorm(10000) > y1 <- rnorm(10000) > > x2 <- rnorm(10000,mean = .3) > y2 <- rnorm(10000,mean = .3) > > rx <- range(x1,x2) > ry <- range(y1,y2) > > str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry)) Formal class 'hexbin' [package "hexbin"] with 16 slots ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ... ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry)) Formal class 'hexbin' [package "hexbin"] with 16 slots ..@ cell : int [1:545] 41 51 75 76 104 107 110 114 136 138 ... ..@ count : int [1:545] 1 1 1 1 1 2 1 1 2 1 ... ..@ xcm : num [1:545] -1.141 1.445 -0.493 -0.324 -0.995 ... ..@ ycm : num [1:545] -3.42 -3.45 -3.24 -3.35 -2.9 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 545 ..@ call : language hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) ..@ xlab : chr "x2" ..@ ylab : chr "y2" ..@ cID : NULL ..@ cAtt : int(0) > > str(erode(bin1)) Formal class 'erodebin' [package "hexbin"] with 19 slots ..@ eroded: logi [1:535] FALSE FALSE FALSE FALSE FALSE FALSE ... ..@ cdfcut: num 0.5 ..@ erode : int [1:71] 12 35 34 57 52 4 30 101 138 150 ... ..@ cell : int [1:535] 16 20 48 70 74 75 76 80 99 101 ... ..@ count : int [1:535] 1 1 1 1 1 1 1 1 1 1 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 30 ..@ shape : num 1 ..@ xbnds : num [1:2] -3.8 4.3 ..@ ybnds : num [1:2] -3.71 4.17 ..@ dimen : num [1:2] 36 31 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > > str(smbin1 <- smooth.hexbin(bin1)) Formal class 'smoothbin' [package "hexbin"] with 17 slots ..@ wts : num [1:3] 48 4 1 ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ... ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 34 ..@ shape : num 1 ..@ xbnds : num [1:2] -4.34 4.84 ..@ ybnds : num [1:2] -4.23 4.7 ..@ dimen : num [1:2] 40 35 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > (smbin2 <- smooth.hexbin(bin2)) 'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35 > > str(erodebin1 <- erode.hexbin(smbin1)) Formal class 'erodebin' [package "hexbin"] with 19 slots ..@ eroded: logi [1:906] FALSE FALSE FALSE FALSE FALSE FALSE ... ..@ cdfcut: num 0.5 ..@ erode : int [1:73] 11 35 95 100 117 88 6 39 167 232 ... ..@ cell : int [1:906] 17 18 19 21 22 23 51 52 53 54 ... ..@ count : int [1:906] 1 1 1 1 1 1 1 4 5 2 ... ..@ xcm : num [1:535] 0.37 1.338 0.721 -1.846 -0.965 ... ..@ ycm : num [1:535] -3.66 -3.71 -3.54 -3.2 -3.24 ... ..@ xbins : num 34 ..@ shape : num 1 ..@ xbnds : num [1:2] -4.34 4.84 ..@ ybnds : num [1:2] -4.23 4.7 ..@ dimen : num [1:2] 40 35 ..@ n : int 10000 ..@ ncells: int 535 ..@ call : language hexbin(x = x1, y = y1, xbnds = rx, ybnds = ry) ..@ xlab : chr "x1" ..@ ylab : chr "y1" ..@ cID : NULL ..@ cAtt : int(0) > (erodebin2 <- erode.hexbin(smbin2)) 'hexbin' object from call: hexbin(x = x2, y = y2, xbnds = rx, ybnds = ry) n = 10000 points in nc = 545 hexagon cells in grid dimensions 40 by 35 > > if(FALSE)## does not work -- what funny stuff is hdiffplot() doing??? + par(mfrow = c(2,1)) > > if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin + hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins") + + hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins") + + plot.new() + hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins") + }# not yet > hexbin/tests/viewp-ex.Rout.save0000644000175100001440000000243312371752266016300 0ustar hornikusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > ## a variation on Nicholas' post to bioconductor & example(hexViewport) > set.seed(545) > x <- rnorm(2^15) > y <- 3*x - .2*x^2 + rnorm(2^15) > hbin <- hexbin(x,y) > > ## > hp <- hexViewport(hbin, newpage = TRUE) > pushHexport(hp) > library("grid") > grid.rect() > grid.xaxis() > grid.yaxis() > grid.hexagons(hbin, style = "centroid") > hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count) > xx <- seq(hbin@xbnds[1], hbin@xbnds[2], length = 500) > grid.lines(xx, predict(hloess, xx), + gp = gpar(col = 'red', lwd = 2), default.units = "native") > popViewport() > > proc.time() user system elapsed 0.368 0.020 0.379 hexbin/tests/hray.R0000644000175100001440000000110111551510077013770 0ustar hornikuserslibrary(hexbin) set.seed(572) x <- rnorm(100) y <- rnorm(100) val <- rnorm(100) inc <- abs(rnorm(100,sd = .3)) loB <- val-inc hiB <- val+inc if(exists("hray", mode="function")) { # 'real soon now' ## no confidence bounds plot(x,y,type = 'n') hray(x,y,val) ## confidence bounds plot(x,y,type = 'n') hray(x,y,val, lo = loB, hi = hiB) ## clockwise orientation plot(x,y,type = 'n') hray(x,y,val, loB, hiB, clockwise = TRUE) ## no tics and small filled dots plot(x,y,type = 'n') hray(x,y,val, loB, hiB, ticlength = FALSE, dotside = 20, dotlength = .025, dotden = -1) } hexbin/tests/hdiffplot.R0000644000175100001440000000160411551510077015014 0ustar hornikuserslibrary(hexbin) if(R.version$major != "1" || as.numeric(R.version$minor) >= 7) RNGversion("1.6") set.seed(213) x1 <- rnorm(10000) y1 <- rnorm(10000) x2 <- rnorm(10000,mean = .3) y2 <- rnorm(10000,mean = .3) rx <- range(x1,x2) ry <- range(y1,y2) str(bin1 <- hexbin(x1,y1, xbnds = rx, ybnds = ry)) str(bin2 <- hexbin(x2,y2, xbnds = rx, ybnds = ry)) str(erode(bin1)) str(smbin1 <- smooth.hexbin(bin1)) (smbin2 <- smooth.hexbin(bin2)) str(erodebin1 <- erode.hexbin(smbin1)) (erodebin2 <- erode.hexbin(smbin2)) if(FALSE)## does not work -- what funny stuff is hdiffplot() doing??? par(mfrow = c(2,1)) if(exists("hdiffplot", mode="function")) { ## not yet in new hexbin hdiffplot(bin1,bin2, main = "Original N(0,*) Random bins") hdiffplot(smbin1,smbin2, main = "smooth.hexbin() smoothed bins") plot.new() hdiffplot(erodebin1,erodebin2, main = "erode.hexbin()d smoothed bins") }# not yet hexbin/tests/hray.Rout.save0000644000175100001440000000246612371752204015475 0ustar hornikusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > set.seed(572) > > x <- rnorm(100) > y <- rnorm(100) > val <- rnorm(100) > inc <- abs(rnorm(100,sd = .3)) > loB <- val-inc > hiB <- val+inc > > if(exists("hray", mode="function")) { # 'real soon now' + + ## no confidence bounds + plot(x,y,type = 'n') + hray(x,y,val) + + ## confidence bounds + plot(x,y,type = 'n') + hray(x,y,val, lo = loB, hi = hiB) + + ## clockwise orientation + plot(x,y,type = 'n') + hray(x,y,val, loB, hiB, clockwise = TRUE) + + ## no tics and small filled dots + plot(x,y,type = 'n') + hray(x,y,val, loB, hiB, ticlength = FALSE, + dotside = 20, dotlength = .025, dotden = -1) + + } > > proc.time() user system elapsed 0.252 0.012 0.258 hexbin/tests/large.R0000644000175100001440000000136211551510077014130 0ustar hornikuserslibrary(hexbin) if(FALSE) { ## the following is still quite a bit from working/useful : ## what should that do? set a palette? rgb <- matrix(c( 15,15,15, 0, 0, 0, 1, 9,15, 9,15, 9, 15, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 2, 7, 0, 7, 1, 8, 1, 1, 15, 2, 2, 11, 1, 1, 8, 1, 1, 5, 1, 1, 5, 1, 1, 15,15,15), ncol = 3, byrow = TRUE) ##ps.options(rasters=600,color=rgb/15,background=2) ##ps.options(color=rgb/15,background=2) postscript("large.ps",width = 10,height = 7.5) plot.hexbin(ans.25mil, style = "nest", lcex = .9) }## FALSE, i.e. nothing done hexbin/tests/large.Rout.save0000644000175100001440000000276712371752246015636 0ustar hornikusers R version 3.1.1 (2014-07-10) -- "Sock it to Me" Copyright (C) 2014 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) R is free software and comes with ABSOLUTELY NO WARRANTY. You are welcome to redistribute it under certain conditions. Type 'license()' or 'licence()' for distribution details. R is a collaborative project with many contributors. Type 'contributors()' for more information and 'citation()' on how to cite R or R packages in publications. Type 'demo()' for some demos, 'help()' for on-line help, or 'help.start()' for an HTML browser interface to help. Type 'q()' to quit R. > library(hexbin) > > if(FALSE) { ## the following is still quite a bit from working/useful : + + ## what should that do? set a palette? + rgb <- matrix(c( + 15,15,15, + + 0, 0, 0, + 1, 9,15, + 9,15, 9, + 15, 9, 9, + + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + 0, 0, 0, + + 9, 9, 9, + 0, 2, 7, + 0, 7, 1, + 8, 1, 1, + + 15, 2, 2, + 11, 1, 1, + 8, 1, 1, + 5, 1, 1, + 5, 1, 1, + 15,15,15), ncol = 3, byrow = TRUE) + + ##ps.options(rasters=600,color=rgb/15,background=2) + ##ps.options(color=rgb/15,background=2) + postscript("large.ps",width = 10,height = 7.5) + + plot.hexbin(ans.25mil, style = "nest", lcex = .9) + + }## FALSE, i.e. nothing done > > proc.time() user system elapsed 0.240 0.032 0.265 hexbin/tests/viewp-ex.R0000644000175100001440000000107212371432145014600 0ustar hornikuserslibrary(hexbin) ## a variation on Nicholas' post to bioconductor & example(hexViewport) set.seed(545) x <- rnorm(2^15) y <- 3*x - .2*x^2 + rnorm(2^15) hbin <- hexbin(x,y) ## hp <- hexViewport(hbin, newpage = TRUE) pushHexport(hp) library("grid") grid.rect() grid.xaxis() grid.yaxis() grid.hexagons(hbin, style = "centroid") hloess <- loess(y ~ x, data = hcell2xy(hbin), weights = hbin @ count) xx <- seq(hbin@xbnds[1], hbin@xbnds[2], length = 500) grid.lines(xx, predict(hloess, xx), gp = gpar(col = 'red', lwd = 2), default.units = "native") popViewport() hexbin/src/0000755000175100001440000000000012565116271012342 5ustar hornikusershexbin/src/hbin.f0000644000175100001440000000365312565116271013440 0ustar hornikusers subroutine hbin(x,y,cell,cnt,xcm,ycm, size, shape, * rx,ry, bnd, n, cellid) C Copyright 1991 C Version Date: September 16, 1994 C Programmer: Dan Carr C Indexing: Left to right, bottom to top C bnd(1) rows, bnd(2) columns C Output: cell ids for non empty cells, revised bnd(1) c optionally also return cellid(1:n) c Copyright (2004) Nicholas Lewin-Koh and Martin Maechler implicit none integer n, nc, cell(*), cnt(*), bnd(2), cellid(*) c cellid(*): length 1 or n double precision x(n), y(n), xcm(*),ycm(*), rx(2),ry(2), size double precision shape integer i, i1, i2, iinc integer j1, j2, jinc integer L, lmax, lat double precision c1, c2, con1, con2, dist1 double precision sx, sy, xmin, ymin, xr, yr logical keepID keepID = (cellid(1) .eq. 0) C_______Constants for scaling the data_____________________________ xmin = rx(1) ymin = ry(1) xr = rx(2)-xmin yr = ry(2)-ymin c1 = size/xr c2 = size*shape/(yr*sqrt(3.)) jinc= bnd(2) lat=jinc+1 iinc= 2*jinc lmax=bnd(1)*bnd(2) con1=.25 con2=1.0/3.0 C_______Binning loop________________________________________ do i=1,n sx = c1 * (x(i) - xmin) sy = c2 * (y(i) - ymin) j1 = sx+.5 i1 = sy+.5 dist1=(sx-j1)**2 + 3.*(sy-i1)**2 if(dist1 .lt. con1) then L=i1*iinc + j1+1 elseif(dist1 .gt. con2) then L=int(sy)*iinc + int(sx)+lat else j2 = sx i2 = sy if(dist1 .le. (sx-j2 -.5)**2 + 3.*(sy-i2 -.5)**2) then L=i1*iinc+ j1+1 else L=i2*iinc+ j2+lat endif endif cnt(L)=cnt(L)+1 if (keepID) cellid(i)=L xcm(L)=xcm(L)+ (x(i)-xcm(L))/cnt(L) ycm(L)=ycm(L)+ (y(i)-ycm(L))/cnt(L) enddo C_______Compression of output________________________________________ nc=0 do L=1,lmax if(cnt(L) .gt. 0) then nc=nc+1 cell(nc)=L cnt(nc)=cnt(L) xcm(nc)=xcm(L) ycm(nc)=ycm(L) endif enddo n=nc bnd(1)=(cell(nc)-1)/bnd(2)+1 return end hexbin/src/hsm.f0000644000175100001440000000360612565116271013305 0ustar hornikusersC File: hsm.f C Programmer: Daniel B. Carr C Version Date: January 3, 1994 C C This program is an hexagon cell smoother. It smooths into C neighboring cells and hence expands. C The kernal is a crude integer kernel. C The boundary hexagons get weight 1, the center hexagon C gets weight, wt, which by default is set to six. C C subroutine hsm(cell,cnt,n,nmax,sm,ncol,wt) implicit none integer n, nmax, ncol integer cell(*), cnt(*), sm(*), wt(*) integer ind, ind1(6), ind2(12),ind3(6), ind4(12), loc integer row, cnt1, cnt2, wta, wtb, wtc integer i, j C__________Constants___________________________________________ ind1(1)=-1 ind1(2)=ncol-1 ind1(3)=ncol ind1(4)=+1 ind1(5)=-ncol ind1(6)=-ncol-1 ind2(1)=-2 ind2(2)=ncol-2 ind2(3)=2*ncol-1 ind2(4)=2*ncol ind2(5)=2*ncol+1 ind2(6)=ncol+1 ind2(7)=2 ind2(8)=-ncol+1 ind2(9)=-2*ncol+1 ind2(10)=-2*ncol ind2(11)=-2*ncol-1 ind2(12)=-ncol-2 ind3(1)=-1 ind3(2)=ncol ind3(3)=ncol+1 ind3(4)=+1 ind3(5)=-ncol+1 ind3(6)=-ncol ind4(1)=-2 ind4(2)=ncol-1 ind4(3)=2*ncol-1 ind4(4)=2*ncol ind4(5)=2*ncol+1 ind4(6)=ncol+2 ind4(7)=2 ind4(8)=-ncol+2 ind4(9)=-2*ncol+1 ind4(10)=-2*ncol ind4(11)=-2*ncol-1 ind4(12)=-ncol-1 wta = wt(1) wtb = wt(2) wtc = wt(3) C_________Smoothing_____________________________________ do i=1,n sm(cell(i))=wta*cnt(i) enddo do i=1,n loc=cell(i) row=(loc-1)/ncol + 1 cnt1=wtb*cnt(i) cnt2=wtc*cnt(i) if(mod(row,2).eq.1)then do j=1,6 ind=loc+ind1(j) sm(ind)=sm(ind)+cnt1 enddo do j=1,12 ind=loc+ind2(j) sm(ind)=sm(ind)+cnt2 enddo else do j=1,6 ind=loc+ind3(j) sm(ind)=sm(ind)+cnt1 enddo do j=1,12 ind=loc+ind4(j) sm(ind)=sm(ind)+cnt2 enddo endif enddo n=0 do i=1,nmax if(sm(i).gt.0)then n=n+1 cell(n)=i cnt(n)=sm(i) endif enddo return end hexbin/src/hcell.f0000644000175100001440000000251512565116271013603 0ustar hornikusers subroutine hcell(x,y,cell,n,size,shape,rx,ry,bnd) C Copyright 1991 C Version Date: September 16, 1994 C Programmer: Dan Carr C Indexing: Left to right, bottom to top C bnd(1) rows, bnd(2) columns C Output: cell ids for none empty cells, revised bnd(1) c implicit none integer n, cell(1), bnd(2) double precision x(1), y(1), rx(2), ry(2), size, shape integer i, i1, i2, iinc integer j1, j2, jinc integer L, lat, celmax double precision c1, c2, con1, con2, dist1 double precision sx, sy, xmin, ymin, xr, yr C_______Constants for scaling the data_____________________________ xmin = rx(1) ymin = ry(1) xr = rx(2)-xmin yr = ry(2)-ymin c1 = size/xr c2 = size*shape/(yr*sqrt(3.)) jinc= bnd(2) lat=jinc+1 iinc= 2*jinc con1=.25 con2=1./3. celmax=0 C_______Binning loop________________________________________ do i=1,n sx = c1 * (x(i) - xmin) sy = c2 * (y(i) - ymin) j1 = sx+.5 i1 = sy+.5 dist1=(sx-j1)**2 + 3.*(sy-i1)**2 if(dist1.lt.con1)then L=i1*iinc+j1+1 elseif(dist1.gt.con2)then L=int(sy)*iinc + int(sx)+lat else j2 = sx i2 = sy if( dist1.le.(sx-j2-.5)**2 + 3. * (sy - i2 -.5)**2) then L=i1*iinc+j1+1 else L=i2*iinc+j2+lat endif endif cell(i)=L celmax = max(celmax,L) enddo bnd(1)=(celmax-1)/bnd(2)+1 return end hexbin/src/herode.f0000644000175100001440000001304112565116271013756 0ustar hornikusersC File: herode.f C Version date: Jan 4, 1994 C Programmer: Daniel B. Carr C C The vector erode returns the gray-level erosion order for hexagon cells. C The erosion cycle is: C cycle = (erode-1)/6 + 1 C Many cells may be eroded in the same cycle C A tie break is the cell count deficit at erosion time: C deficit=erode - 6*cycle C The last eroded cell might be considered a bivariate median C C The algorithm: C Repeat until no cells are left in the list. C Process list C Reduce the cell counts by the a multiple of exposed sides C If a cell count is zero or less after an erosion cycle C let order=order + 6 C report erode = order + cell count (count is <= 0) C remove the cell from consideration C update exposed side counts for existing neighbor cells C if exposed sides was zero, temporarily store id's C else C compress list C endif C Add temporarily stored id's to list C End Repeat subroutine herode(cell,cnt,n,bdim, * erode,ncnt,ncell,sides,neib,exist) C C implicit none integer cell(*), cnt(*) ! cell id and count integer n, bdim(2) ! number of cells and 2-D array bounds integer erode(*) ! erosion status integer ncell(*),ncnt(*) ! extracted id's and expanded counts integer sides(*) ! number of exposed sides integer neib(6,*) ! pointers to the neighbors logical exist(0:*) ! cell existence integer nrow, ncol, Lmax ! dimensions integer inc1(6), inc2(6) ! increments to get neighbors integer i, icell, j, k, L ! subscripts integer nc, nnc, nb, ninc, r, c !more subscripts integer loop, order, maxcnt C_______Zero cell ordering numbers________________________________ order=0 C_______Load the increment arrays and constants nrow = bdim(1) ncol = bdim(2) Lmax = nrow * ncol nnc = n C______Load increment arrays to neigbors______________ C C order=right, up left, down left, up right, left, down right inc1(1)= 1 inc1(2)= ncol-1 inc1(3)= -ncol-1 inc1(4)= ncol inc1(5)=-1 inc1(6)= -ncol inc2(1)= 1 inc2(2)= ncol inc2(3)= -ncol inc2(4)= ncol+1 inc2(5)=-1 inc2(6)= -ncol+1 c_______load working arrays_______________________________________________ do i=0,Lmax exist(i)=.false. enddo maxcnt=0 do i=1,n icell=cell(i) ncnt(icell)=cnt(i) exist(icell)=.true. maxcnt=max(maxcnt,cnt(i)) enddo C_______Store pointers to cell neighbors_________________________ C C A pointer of 0 means the neigbor in out of bounds C Also find the max count C Speed: Can avoid adding 1's to r and c C but this code is easier to follow do i=1,n L=cell(i) k = L -1 r=k/ncol+1 c=mod(k,ncol)+1 if(mod(r,2).eq.1)then do j = 1,6 neib(j,L) = L + inc1(j) enddo if (c .eq. 1) then neib(2,L) = 0 neib(3,L) = 0 neib(5,L) = 0 else if (c .eq. ncol) then neib(1,L) = 0 endif if (r .eq. 1) then neib(3,L) = 0 neib(6,L) = 0 else if(r.eq.nrow)then neib(2,L) = 0 neib(4,L) =0 endif else do j= 1,6 neib(j,L) = L + inc2(j) enddo if (c .eq. 1) then neib(5,L) = 0 else if (c .eq. ncol) then neib(1,L) = 0 neib(4,L) = 0 neib(6,L) = 0 endif if (r .eq. nrow) then neib(2,L) = 0 neib(4,L) = 0 endif endif enddo C_______Count exposed sides for cells in the contour_________________ do i=1,n icell=cell(i) sides(icell)=0 do j=1,6 if(.not. exist( neib(j,icell) ) )then sides(icell)=sides(icell)+ 1 endif enddo enddo C________Grab surface cells___________________________________________ nc=0 do i=1,n if(sides(cell(i)).gt.0)then nc=nc+1 ncell(nc)=cell(i) endif enddo n=nc !n is now the number of exposed, non-empty cells C_______The outer loop________________________________________________ C C temporary indices C nc: index for cells remaining on the list C ninc: index for newly exposed cells added to back of list do while(n.gt.0) C Subtract exposed-side counts from the surface cell counts C until at least one cell is empty. loop=maxcnt do i=1,n icell=ncell(i) loop=min( (ncnt(icell)-1)/sides(icell) , loop) enddo loop=loop+1 !all loop values are 1 too small C update the counts, rank and remove eroded cells nc=0 order=order+6 ninc=n do i=1,n icell=ncell(i) ncnt(icell)=ncnt(icell)-sides(icell)*loop if(ncnt(icell).le.0)then C Remove the empty cell and store it's order exist(icell)=.false. erode(icell)=order+ncnt(icell) C Update the neighbors of the empty cell do j=1,6 nb=neib(j,icell) if(exist(nb))then C Store cells for addition to surface list if(sides(nb).eq.0)then ninc=ninc+1 ncell(ninc)=nb endif C Update sides for the neighbors sides(nb)=sides(nb)+1 endif enddo else C Save remaining cells nc=nc+1 ncell(nc)=ncell(i) endif enddo C Add new surface cells if any do i=n+1,ninc,1 nc=nc+1 ncell(nc)=ncell(i) enddo n=nc enddo C_______compress result___________________________________________ do i=1,nnc erode(i)=erode(cell(i)) enddo n=nnc return end hexbin/NAMESPACE0000644000175100001440000000432411551510077012771 0ustar hornikusersuseDynLib(hexbin) import(methods) import(grid) ## too many things from grid import(lattice) ## too many things from lattice importFrom(graphics, plot, polygon) importFrom(grDevices, col2rgb, gray, grey, hsv, rgb, rgb2hsv, xy.coords) importFrom(stats, coef, density, IQR, loess, loess.control, median, predict, update) importFrom(utils, modifyList, str) ## Generics and functions defined in this package export( "erode", "erode.hexbin", "getHMedian", ## document those; the method aliases are there: ## "getFig", "getMargins", "getPlt", "getXscale", "getYscale", "gplot.hexbin", "grid.hexagons", "grid.hexlegend", "hboxplot", "hcell2xy", "hexbin", "hexcoords", "hexList", "hexpolygon", "hexViewport", "hexVP.abline", "plotMAhex", "hexVP.loess", "hexMA.loess", "hsmooth", "list2hexList", "pushHexport", "smooth.hexbin", "hdiffplot", # but not all the helpers in ./R/hdiffplot.R ## Stuff in hexutils "hcell2xyInt", "hgridcent", "hexGraphPaper", "hexTapply", "optShape", "inout.hex", ## color stuff "BTC", "BTY", "LinGray", "LinOCS", "heat.ob", "magent","plinrain", ## Lattice stuff: ## high-level functions "hexbinplot", "hexplom", ## panel functions "panel.hexbinplot", "panel.hexplom", "panel.hexboxplot", "panel.hexgrid","panel.hexloess", ## utilities "hexlegendGrob") ## S3 methods for lattice-type functions S3method("hexbinplot", "formula") S3method("hexplom", "formula") S3method("hexplom", "matrix") S3method("hexplom", "data.frame") exportClasses("hexbin", "erodebin", "smoothbin", "hexVP", # could/should we keep this 'private' (?) : "integer or NULL", "hexbinList" ) exportMethods( "erode", ## undocumented: "getFig", "getMargins", "getPlt", "getXscale", "getYscale", "hsmooth", "plot", "summary", "show", "coerce" ) hexbin/data/0000755000175100001440000000000011551510077012460 5ustar hornikusershexbin/data/NHANES.rda0000644000175100001440000047543611551510077014147 0ustar hornikusers;,IvW\pfZ2.,_o9R34v8zeѢ!ʢEk=Z}ZE!:+5Gʪʬ/ͬȈsNW8O^jVY/~[~ǿ'/|ۻV5&{w^1mylǾ?5>0 90w S=K;7ߜ:\qÿ->JwܝWԴ;\O33f:c˦KL)r29gѕbN8e,Ωcvʸ_>?uc=ٲs9i=o\\0M:1pkǧTspn4:wLnT>CKS;_v3Fs˔qZc|??5k>5o9ssxgX~ ޘb=S{l_Su,eǦTs_>7ƌԺ~ngڽKٜ!?_\𛎁c#yDZ]O9OץlSΩ8=GL9_L1˵`:)ejq ?Rҥt۹}vTv%5\g9WN%NǧysCuͫ9tO~)>u钼8MsڹN?5|s޵K1UxM|WjȻ׆町S_%|ה9׎E:\9ׄrv-nMy| Z/W7r?t)Z5=TZ,MO_z.\S}}ϗ E\=Rckt7s+tY.vZڒ)1)}\kg]-?q(3X.1;wǴI}5rڼ>/~[~?_ӟ|?yO~?eZ}.ǟ;KإKF@cۿL4c`>vc2UsҬ7.S7^nnk ٜץKk\sf<^ؽ%cO{N{5e oj?ZssRl%wYמ3NK*_~/Vqω3O 4ٟ 1h57-uzq._j6N]YRi zc<5.m7_.5_X>i|r< oߵST٘zεOiO~_K 63mt]]'Flڼ:s>RbNKx.K/zMޘߏ4[yv.wu|{.lz 4=5M%. ͧb %9w[wxmI\o]TEwcqX_tʺؒֈ>7aiSRa]F%|N%%646M;""K›] wskNåz)p\ uX-M[X/7k"wi{h_㔟n^< N0oo?\.? {-wa^LÔ =p<yl3z<Csj;hzO a7#Ṧ^ތ[1 'G?g̷ A/R?+#/C8y| \ЃqPso:x'I }hVצּ>|{CΩWKRB'}Xi>K=Tt_<;o}D%I)Cj~?A'tϸ]?_Z_.pp )>aI}~n^+ibJ~i'Ѕvq[d3~ivr>O#aI= D>s> }koAߒG/RvxWϯ@ڮ7qi|W~fY?Wr[葢!v~_'Ёz?;_3=`ONCnз -BOsZR߯diƑO BO8~ƍۛ!<ԣ}z){;rƒ\J{?R}Cyܴo=Vv)ϡ#픾<>c?shGwW,sz{[zߚR"MJ| 7i>}_?YJi;^}i8=;p=R}AWO#7#q6#+z^x tuJ8ῲ >oE׼@k? _>+/WgZ|WQooͰ_oۮ0k q)e_pBGo{@;zyzx<>>v>B?:e;oJ~v >/cWwܥoSCſ!7!q(߉gCWrm9L G#o;s_t Kya;[wk$c+J}ƻ]+,L =ϲ(x;|J'jG?7zW3^姬]~^n^Hsyc:JvjCm/~ 񶟆^\W~T,=Y w|zW|US +s3v/?7Cxv.}+I¿Ǵ~{kW/u?6Cji.^o= ݡkz5,ߡ缞b儏S_r߁罚gop u|qOxz92[<|3:pz5޶sZ Fn"G>j➛a{A?N_s|vk|C?Z KA=߂.t_βvQ;ha|nXn_Y?Ag2ncǽ+ƭo_x#x˟S.p>s3.%gz;У!{ UgO3^_B/T<0ϡ9jA;_:κy>; _"G?x=|nvz6ZIuISuհ=>(8!:1C\ b<_ʽ՜'g;yB|G){eo7C|=_B|?_/;~W*~-/=.ubZ,k}{yzozدuZET}5Ͱwxr+~|;~>=˟Ke|~>=s~^hx>OA?*o/zN޳?[~7qyHё_~~Vz_:|?C_DZl//㋌izS}[~z 瑠=[k8og|;^}TgއO=t(yܴa=={RY=u/=#tq;s_ya{enyoq;|xsq7})^Q5[ rLS)};/^C><_^u^4핿y|oy?yug'>;;&9N.x :{Pyz_{UmG+?<ϡwë^8N8K[W~u_+>t)N//{QRq6{vx?e)?޵.>Lo _?ٯqܳy<po}ީ}e{u}RIcǮ؎;;?л;paֺ/=v x/WElK;ؔο>ӏy==VUyO{;o[{}_meo{WD~1?q:$}㐵&֫aYys8r`;fOxHϔ&|G<˳3x;x?gC/Ǔ|QЏާLF oebs_/}7Cx{َӏ뼚W|2z5cyKJC+R@g "<'uJljY߇N>BG'؟qʗ_ ۩LN5T>R9O'x_>GN,?CȟکuW~~G;ctۏډ :ܕ=;Տ!}ng=~{|v5|u Ys_};5<;z>/rh냊Оڭ8~J)-WnWT=o-{{cZ?z~~9.S~;~K=Doq]Sz=Ny>۔߳<~uJW~zw/3wΗKsUv |^yZpg'.≼:Z=>{j?z!o ;xVq=_cǿI;yoYgywKd.ǃ-_;=~MɇUxc#އ[tH=ox w˱ƒ^Q;>Cu>3+uw5z>' a>7qη9~}tI?s)m?ˮqo 5J|cxr_nGlǩ_Rzu'oCy)xtܗR:ݴy~$a8|NfXJ}W>>QAY{a{_~ZW{x:>޻g{w~9}z5!)=^uC8}'sR'o_#gΧ/S]Y^ODZ2<ya׫a|P;7@/;swVw9%wo8^؍{w9iXPϥ:}TrFpgG*=oY~ ::|Y;^W὿sYSz@^GC?*Axk3,gίG%e;GR߿v=a7?ϲ穿νi<; )ws~cf·*s*>y^5z~[l)UqgBobާR9C8%ճ23y?bo{KjPTl[{[>nMJ7jGa8ydv+Mj'B} w|:5v~9.RX.xgsۃ:g"|eBM9ay8ԾДh'v-{ށ;ϻw|ʧZ\|3 x|N yyIO?޴',9RZ?~?8kM~yzX7r+ۮߝ76{/of8 ?aԏٕO8QQ+_a3||N|c{FRzfUa}_tx9zwO_uLw/>ϜxVp :'Ԯ{SR9'Σj}y<v\}ˤ]O}·7Mewg:{}Cw=ǟ-we7nǯNs;*͇>w귾״(Y/9$_=){,xs^ϯ8qyD;M>G#xc^q6q~]? ϫ|ބ3*WYwPi9!{5S=G9i<۴νz:x^쎋؎OK\<^C_Hw]W|Jſryn{}Z=#7?{c;Hi!p}~O^Y3su~>?;=y>ک8ڷe?n|J|y/GVW/_'/y}*O^o^͓y~;"zHz!y\x`?FrO;GW;7γ<㥟V~%T]sk}~sϳ;q#k9?2zsor8sΰswO|zۿi8=L8gq7v 6vWyO>73>:Y!|.m}[y!)}*Lﳶ_WfXcqӬzD~َ'r'ψow{]XOz]~syLIZ;ߵS!;lp8fo}|~Ѝ~w\fck<8\g_}shߣ|y;6C8jt>~'o<>w,>7ϽsO;y SwgSzq:3la'.t;,V~m}zv#7;w˝sW~|.Ù<;ɛa{YnUwΟS?|o>__8鼖&NE;~I{;q4捶W7Z?:/J?Λ9_O+T[x[X}ǿ }{wgsha={'0?Y^~7y?LJgν>!qUAp|q^ױs̿o~GoO$կ)}~Ak[8u.=_?S~zWcI١/ί>]=DZ>)mwʏ wVv=Vl*C8 e~w}:}nOy/{>Y߼V˽~w^ovs7g>:|IǻNNYYPOp9A{l߼/rRoc烈fn}/%:Za}k{o}8kMp?c/+?&e}o\{ݲS2u'zx|losj&g<wCٛ{~U?ɝTxn~{fX__m)q\S>ӝ~*NT>E9}./-γxnJC)}skhy߫!~umnؿq\N'\իu=^}30Oˑ;_tt^wcvSsqZLuބz_8<}vi?Χ'Gp?t>wQtz瑽u7ϫ!!|s獭Os7j;.ysͧi?CJ;e}gO9%xx}yz=Jy^d\塚%~_ 4j}"xVf3シ6W>^OJ[:.sy{٥u˗YG}ycNqHr~C^OÏ:Np.>A;|@{c6-}W^;g}Z}M_?sm5;[^:e u\v^窭= KGˎRCxw{uޚxz?PҎl=}>bsNN}a5ʯ^u>j؟!}|z:Nqa81eS9_)oRz>DWq{_76~Gf3,=/L=*5%tb=o:'__Qw{,%!!/^v~uw>8.|j{ϗ>V}~g9F^_c4;\^m ynO9v-7oKޗ}ާE?^fޚ2+UX?s|X{5?^/W}Y,]ǡ~ mwx?t=q^\'/߬۾z^yϥNs{{>P=x^gڻλ'X +Rz3 WGc}·NMxy=4!Ou娷iȽׁ/{^/*.K)yѝPRo-|fYs:^8 ;kӜ'c;>e<uJO^Ϗ^/qϢr;z묌}xwò)}7{->{;߸+wo~}i:6>vGێ| ;齟F|/8׫!?1 =owyoBWO.x㾎Ϧc; <}#Xq>B;>#8zq#o7?=>rGM[q=N}΢|e\gX 9,w_P=l'^'|Jw:~pFx\;9a5N<ǭ5]]Am{}\޹s^{w^[n*)yS~ρw4'{Px_={un<6G>_|y89n};,yot 9^u Ǖovwϛ׫)-=^ӹΙ˽Ľ=xfXqTʚoЏ Kso{SOvb߉+wGOLW߭v^Nš6~O;azn侗wu^GA^c Ϸ_0]+*>=}eg6Cւz}j=p7;y‡z\M:广yWσ?ޯzeHyMWG8E;_:kν#{#׽z=N˹i'3+?vz5xvrYy^ozp7ӎTP9Dzxwx~u:|x?:޵ū}a:ku'>7ˎzǝ}.y;ގ?8O~띛a==yTmzB'{}=އo=X ,Yyg9}x[7Rz~g98?>o{@9*jA.\u3ݼ?\x|\y u'}I :oy^߀_!x]֫a}vޔy?m^_yc>/DZ踈*k8U;siN6vϲa*T{=<|ZM ?|]S)|i3l|)[ʾwo|ߎKHzNj)yZ}{߻){?ܿwӳwWw>UU~oӸ:[}Ր4xSc德2[cNvkݷkmp[1^^}kLl]nleYiU---nv۸dcӒw?֖ _ {-3-YnѧoO_zO}Bm޴ٕ[cͣ0İ6]ɦulYnZ&mϬS=[d۳4Ѹ/jCpm_clײ%cgz{5.{yk̷i4F7덛ig|ZJ_ӽgK>[vų9-5-7,=ޱ.[Ӈ^ؘ--jٌNn飞q[[߸o렞LuO/ֽa~_m?mtpO[}oLw{G[}zm3/e.٧Z:}l;`j6)ճA-lg=`K-ù֘l?Sļ> -ѾsMseϰy4il3Ӟ]lm>?.lm{6i]lmҶhɼmlۖݖygզMWKwXNyz:%c2m;aybKFikzikǽ--;m:[wwWu5eK?ۮ5vo n@OZ>0[z-}7c_';=F-goz2ز-ccqheך?=}߻m'Zc`=o뉖\غn?ij#zrc+-xl8{Mnw-ۓ]m^1,==-0iۣmKߖlZӭzy~fZl۷e[ng^ }lgfk:e[`nc7-Zg+cL1 =,旞n%_:' -?;]9XgmZ;=5MO=Zxpiѯ5F3?-YOk?nܼgs[:m-K-}-=e<{cޚ#tFqms[t^H-=j_׾a}K}}=x<۸za۰oM}cF}ԣmGZ{2my㡖x쓹no0}mXzzƾ5=\-XZsOy=-lkmlZ<߲9cdb~EOӺ7-;O&[|nm[|ҁ-ݢ>u ϾO^J˾d-~1o{g=b҃}ۣA z짌ˡv{8m߳-$7ζ-݊l{~6-!^=ezzl[|>﫽wV4:$k-XѢGo,[kwz[cGY% -`}g[sVlmY84v>jSK7'=}V?7l㸏Zx7?1soNYo^iڶ|,˥!m}ٲՒQB~oQmUl_kLZ|ۼHW=۴7̭nUOݖ,6=\iВcO[`o=W-0>-zde؂g_O!zehqkp,Ƿ=hqw9û* !?t9ұnuKVT=[ Cϡg}̞mi?h]5›t`[m6=١G}}ٶТc?Zx֕5[|o<{1}k{1m1n>~?V^_xT}4oQtо~#s|v.߶s}sm}-oN8o/jO/ЊgOo0n:z1vs{ov-;O>Z39$۽hOnZ2qomy%87fc^ۖ3ik[nSGoLoǿ%[1}m_ݞ~81s3_!8ϴtXָ}tݧZrԪߋvt!yۧ7i}}i5f~O&[ynM}[cGk^ ool[nml/FeϭZ@K=nu6ánVkwz%-xZcO`'aXwƭ!7k7&c>z1^={Ohw'qx}L-湞[{~dK. ÷O7t>;gikzƻb_g<6-v^0x}d~?⅞n!_nN+nq}٘}vq~g>Ѩ'[&wڶӭq~oגV_z56UO[7w ^[wce-Ӳ7mz7nhnzHŨz|s}moHb>l6-C>_Ϗ4룥[П'z3泖niѻwtvݖ\y/.ٓ-L?۳m->LxhvH쓿ksl_1s1}j瘶<[g}CbXXnjݧͥt==}Z=lR!g-ncޓuچ5Ug_|:gO{m}cjӂCcks{X\ǯoN=b=c^Ѡ%dGyԡy~O[Ӄz=jq.eh_[[lӦNϮG⼽y؃o?%6wHbk{}l?ĪNiw݇Y;ncV-J}z>lu7ءC_P^ǶDZ폽ΥשkoKӹ|4u.sSM5S{)8k=5_[P;s+S]sۥ\=3u;^O3K՛:՞jo.}|w\=15~S]Ssc?u0?ySkX;rNm\Xy>=v*{Kũc+gsqJ΅R=?|ۮ굮SSS?\vhj_w:Un旹MS_S}]z\zt9Sw*;0|ӱkכ&KKgmpsS?wku~ͩtNw^}ޙއX=27<Ƕ{>}۹X{߱Ucʟz^6jT}m:]_{z~=wj;K kq׵u}M5:qjs?cۙK̥\ױcߟԼq.X~K?/5O}T<ɹS`j{k}έO]cc:߱7{ Tu.]ڎO=OO~Z7~^slKr|p*~Ω~pKѡkn{5|?W?KS.MuډST~gn>:/4>S٣sS35uNXy*|߱+OǎåKwݺ5xyƵ\ztNkn=4|*tk¥m.еt,cƹ:;/^ۿ\t6'8xLscssm]S۽s1ӱwl;qkM\zj{)}.y|Scӱ6U|sjy[z|uvOߥ)~]}:wux+?K]?] ũץq:c\xM}./usxo.w*=8εs+sO澦յ:v.NOYuun^׊;.u~6W\v)k]cNq/5k'约#/}M'\O=KKs}nrKTO'8w:]<ظȩ_꽩?kqkip]MTr8ݽTP{νo.Y|w\^O΃ ǩRu\cǩԵ8ϥc`8T׹qͱǥ~˹zhqi2W<ɩK۱]M.}]kan;8ךL.u+oF8˹qڱvG?v.});uxıES\3^ڹsߩc*{8W\?gj~4.8M58VߞOOġ.Sɱ_Z*\K֡>Zޥ|jylSǻN#. ס;Tqcj4{ϱRsZtYri{wi9~ӮKTϭ/*w?zZc9֏;\~q>6^rm*<.߯ew'ݵZzv.e>~)~8ןKk:S5ݕqZL޹T~α퇞ϝKKOt{{*?_[~~~ձ{~zj/vsϩcṔ^=u77^?s=7u.4ݺ58?{lֿ]>v~yl;c;޹ץϩ/EMݕRp.}4US7S] Nmn{qv~\޵={]ov-eZqk['>??:~95|Tqc۟گvqo;ߩskmk]򋦾t/V\<ko*/}ypmx ]X{ױ?CzJS=:֛sߛ ޻^rC\xZR=kw~_o*=M\Vumy s ߹OE5 ߡߧ~wi{<{Rze~Zp]k{l|p)c{c¡~ǎX8c۟Jn. ϡwn;c^7s;USvmPkn|R:7>kjǶ{Cxqj\s:N>~K̭ƶۻ.-S{躴9]߱pw)]צr{_ޗ}9wum84z:kc:׻?ޱM=~Ƕsl{c9TPc9c۽/UΩg:\~kw_.6wcۙK;{;7}Nk*|jgit?ߩc-\kipzޗ}9%snS3~䚺}4y/%ֻ/r%׵6~;co}*.ϩ] Ωx,ܮcx]ksWR|XNTxwX~~nKKmu=_o+2>oKuW]KccR|r.|77?|\|݃gl{}mr:U/˷wK_CO-colavշ>/ Vr][ͥt]׆lum87um8T \SݻNs,c;c;K?wcwss5^,Rƾt=07\\O%KTp,Kmvcu*]|l{9S]͡z?sǩwc%?c9N??4R!xk.?7=/TޡUԸ׿{MEc*cOSnk{ylSc`.q*?+scᝪK}._Sw)-pTki7Ͻw.o*8k*y6_NGk,Lߗ}\oK}y_ޗS\Wl^=3s*: g;S}m9Kש\O}o*=q*][oޗPSc;^wjq,߫?\t>sZr55,/k }f\?Z*n~on: Ϲxcۛޱ΅wjץj.~4u[v55_;nSs8>+sS?Oc,\Jw \pR=wǖ?۩\}xL5Ǝ/?~.\=Vz>:/VuWw-t}y[/ry%׵Xzu{_Kkñ4xPMkk{5S:?]ݩ|=8ӡzsj}vn?KxKk̅R軴vw/rY%\]\uz/C]7}y^ɵPFk}_ޗ}y_ޗwusSS=Uڝ/7ul{Pc8Cc/߮pܗwumxk)ܕw*߃$x>0Gtɟn88|<ΌU'x|^q!_ C|~Ѓq|Sq^0x|'_,%pA<OJϸ/Wѿ|$|$4p>K{Y}~x3^/ϳ:N 료giE1/Bc7_Їz5 ?>@/4^iiI{"iQ{iCOO7|yiڃ rC}Rz9|8>8#l{qȧßOi=>  |*|:`G~oQ0bG/^~?xzy;ǧ.> ߃ϓ }zPnћߠ/Гyϡ_9E^F7أge=\4!/ п˳2|w AQ2pC_aЗq_G˞CÌKєO"G_<"ɓ^wqz!ݡC5?sѫ ?|0Y G/> /C}>bsƋc7r:|H{y<"/ѡ7vq|v^O{a襗pb0^aYJ-㌼_z?x0OcމG|O#`oKƁW/ة)S}o3_>=t{/+#qދg񯆎){#Cײiz9{BO<||= e<@׌;ٓz_`W<^K.3NЏ\@y}~-53Ra x }wѻп3 ?};r'COC }<ʯEc|<}J'8q rN?s0h﯆|:o߳/R%rxaB~|{0"|? e'Cq@|: Ǐ)c_~ߞze]>{>F=Ů7F_e3 *cGs_9~ͳ7vC`~GџOCwEx?&Tq3]B<FA|i~B_~/5@N8+= O/ _Ў<{gCOR/_> At̳k3?/b+>sS) 1x5_~s3]v*]O?g]^f> G7~!t4xc'+. y^!*>= Oě~U_.a't/8[@Џy9ϱL?9[5x420 Wq<!Ndg]z#e|X/0pH=xOi ^2ie<2qƋZoH=[ ,|\GG~G䭰Uz/ԺWu`Y+~ IyE^>*>znbL| ;Uq4"qw/dh߈>Ժz8>8Y7xN\Ԍ'zZG Wاj~7ï&RٴcW |?_<|> _A'e'tf~||OO*^ ̫+?;#Q∥'UUb?@O'r0x> ۭxri80D_'_R/t@ϣoOBg8'Rocj9 T<4:P7By87v|Y_a}ա< ?G*2pNX/~7&t*~ ?b7i;2>}^ij]=p}?qb\*+9f]y"yx?C;@ vxF7 M;Yb7_رơiyQ~#^yyE~|7J~ȯ"?*=sA5Q{yno zq3 \5/HI?-=W1'yu}^~i%zA?_yZ q!K/XOd>_I|Z`WG'CU<$bj˴G ~9 }ȳ~$dg_O'{ =g>C8F'xgߕ|Ydyi?:xG1XDj卥?| }Goa_+!^y oE}#n]G_W^GUq/xBN7 Wxi?푟2UOCOχz }wd\YxP.J_f\`ߙa> _LkS`;^j?f~EY#;q+/|qAA/xbOik_;I??2?D/z>y3ɫb=y!"d}ס5 =~_A?Fbo*>v.#ׁrVӁk#k_$/1xoQsk.WmO$>|<Zii.v{><~^gYq(}*Nݥ}hā/='шy/Y/Nnz/~|~ ~`+; >~/;~ yaǡSͧЇ?0ԫ_2(\e/䟱'=  3zr'>ғ8W[SyOc^?Ty?y|1&/Bo'#_ֿg\Gbk5pb'0.#o_G'x}3yw;k^׈[O*2Ǯ8)xG`e?o/i/x^' վ>\|j/𰎀Ћ<{W|㏡Oޯ Bob3??k'Eg#gYݼ|8~G' e]Wv|v~[rEO=|k_7j~uґqkuc]yHwr_סI\T\"te;Z_A/wgQy*q͸'z} ~^O>*t7(/?_o_O{f|E~C7-$S-0PoA*_!᧐xz(/7w`? yv,GG)!Wr=_7ӹ| yF3*!>nz+2{Ƹy$ȫ9u ڏ0?u᠟[p\'/Cwz5]?3~+!~u |zɧy? /U~Pi8KB}7'y^#^1>KoƳ~/ ̿9g8wP8G8g\f]y?ҟ7hA'-{r﫭}u0OEV>6b8ׇy܇_z d_O'J/z*i7:w% eg"e2n< Ժ&rϡ7vTDgSC;|ހGxt ~uy J;}|ЗxaSŧfu!~xڅOC^ E~!~;y*yGܥ7g٩Wqތ NnoެӳYdEykŃ'"ɾ1v \+3G}y j_r4WA7~U|nTe\XOkf/'PDy)S`>F9y=C f]C=Xp7V~VV+&ZgC/ׁOgޣ?WkT+GnXǴ_ߨs::[qz=G ?jw.+ʸ־W{o@:WU1~sg|u~e^M~W9=o wF/qʫEoǡ70%5?H:}>|1JRwt=,łQ5T SyIv}g_Qd|xrR>;jGwa'J.CműC?? |>v?8OGG!>?v<3Zfv_:~Cd廦>I7/ *?ya~ʳN=m{j*g=y<?y({z_ㄟ+_? pOȼT܊*:W&W6K.|;Ae|98FWOק=GTW>>8kwEO/O>!]+#WWO ~3p~d~Qys4Vʯ }cãW ?m{5_z>2r}*1O9P/q7C<GAڣ(`?j597 \_Ny 3Gs>t!^Y^s|Cf*9?|/urq)'p[NK_=N\52/#c) v@:G`u^}RWn|^X%OyNγ='x+!^uƷkd*~6v-t%]矇ڴ璖ȯJ/0O3uoF؉uzēK3X!΂~u7K+3CܓXS ߩg}"sn|X^Z Iп/)kve *"87te3N\eɏs>\?~C: #Gu>F-}C ;U'C9#^Sؑگz]:~ |Zy! ԺNUxe뜹[^ӡxeWz@k؇xCrq|,p;Gaa?7):%%?A~t%NƵ`X. 腼}c1k,} <_= ʟCcScI :&xcϟ1)ˏp?"oac[%b>7G9G$yuNr=L7=ϸ?=jlc_m/fzW峄/p2zy)U^A/ T<y#k}5xԺ[A<:<Q]gGwg8wC:oS :_~~ugƭAM; G僧=ռ"ezLv 5ߋWZ2K@zuN^9tw1^nPګ}5ċ=%<+wC;ިЮaGּW[I}/"@~d_a_"ǧ1=+ kn0󉒋<'>VV9|>e}\W2_:VCM+|ǵ9^=uNeکMZ< ykSRyAwkW(K˰ |:8_.9^WqAr]Х]ơaG9yǸ/u.!x>q\N·r؏S2_#}y^?釼=ġj>G_r~3u_".ۚ>/~D0>.7 aw'pF<>彊D:?z{ _r^Tun_q>AϺ'G ~?]y?_Uf컬sӠCa,vЏ߉GI_og#_8'q7M~0S~ )=8 tccK?E?3O𓊾?{|[*4>>?=tCi/'j?S'}> S~ԏyv*>0 =3*/"|^,tETzv^|w׹./H}u\е2~#|v> U^G䎸#ECFN{}$bk_rƕ G*^<δG>q?~9niÔw r }k~by^yO1ƾT>0WGqbZOK뜕)p?^n;yCگy@/;ܥ=~ !Zs+q芿Aԯ򅏸/x.JM'|y΍/pfO`rV߳P~?/zs :C?#I` G7yj?|Az7_37s+";xAoƟxX~CGF~r '}]~f<ڿ?:<0C7 _3^?ůF 7Kz!ǡ;yD7p F>xVx^{U]O*o235O.E_o73>~}-g}Q7K9(8=y>3.>7Bcg}W׆8_ngAGCo+N8笻SscW_د-E;K}|q2_|.|qq|} ԏ\/7#ӵΔq7v{wuއ}ڸҮ-*FHD8|H<3CҲ˨e[ MwZeYiVh*@Z (xQ@EA߉~\:׹udgzY{ɟ_؇J7Ӿ}i: [>SS, =vÏ37_FT p칆]?2~yJ) l~=tq<2|Nވ 8;Z;=Nif\(::>G~?Z}!ߑw*~/zro[Ao|SO[v)u|C3 Ϳ6淩 Ih@ɋ}z=:7~rK=Ed\7=pk^x՞/| 427#̣$Oiߐ1w%}B)g?|=i)*xwګ/߻WÕ|| ݛo&pCx KsC[vSҧ$~Ye'G#_?+sds럮Rw6ޮ7g}x!h^aOK#a5 4g~ yktNbO _DJ޾Wݧ__+L^I|{_7|W)8V?aOW/j/!c./J39?ہs |]3yO?s/5i#9:hnӼlWC$YB:9JOWdNیŕoxO? j>cҏu|<o7_d|('oongzyCX6zoZY5^+7s#лxN~8~tt\ursO9PGW_o׮&_Bgi~'+I{7̣87~oǩW?5:{7_ou2pi~k|$ߍRjߒ?o󵄮~ |\o~̋__|v ~Iޗ|%72|<;`'p[ {>1r3諒7Cǥ=A9y/r4 ~y<.2/ uT޳W&C|o}E;GC7'_duϝ~"۸? ?V?7h.{?'%|q?8xxYa_2^:Lx='Ǭ?z%tcnqv>uy(Y#ߍߡcv<:~$c<|N H=oO?:΋`eͻy˳Ҽp{>$ugG:q;7YvI# =Wx3~gƙ;}DO;b93ϞwIHW{,6s|7x=ρ.ݣ7[k].ΩtvUyȇ#.=F+p4yotuc>ֱ= <0>r:gO_4eAo i |_ikW_}c|ȯ#MwyysE7A2Ư;Y[g{yd_msgy<\,?+6Pc/4wѡ)cx|I{Nb3>v87"O.iD4=~苔'Np~;ϸnN?R|m}sLnΑ6.(ݥWbw~&o]"~Os'ā޸_}8_nR?^c\E.=7z?MKy#͗yG}xC|4>-Ů W]"gn$~'g?9L7: ;pN,?d^b3=zN4ܼZg׸/1xy^}nxez_}_]#y}̇fGXwt:xTdW~W sv'xk#tlOu_}|{wi&xj<3ݴ8ڑ#A!\Co/&=OK/ܛyq Wyuȏ3r _e{W >!_ݷ4ΌNg!ǞqId<[r\{]U.(WJNxȗwV?Z|~Czwͻo/>U]%O4o`O;l{|K}ȉƃe_\C-7~A <{n"Ż g:a ~;iqKwK?|3pA_BgޛS_d݇(>=e\mmO&pw|7^yg]eݪ^聼 ڟ}oF.jDۃ<-3?rd]|]xghIWg\_|_H'ydtL>#^788]:k -ռ_;iMϋ~/UcC}N[5t Ӥ}+.i%6ϟKIyWw%z=>E6<+w|Ȯ;^${믏^9}_{$GU~tCM,=];5#a$2#x ?H;g=_Bҧppuyƫ̗^пͧGIk0\Ȍ!W׺wow4fڡ?ޏN^zwqFI_udХL]]ˌy6?Oqp_RaX3>8zʸyAw?/8ݟ3v$>!̟_Q/vWwOs9g빝׸?c?S#?q:2ϞS?#4/Yg߃ϏD\yIo_C_}h}d^|[꽿_2~mH!r~=xqSE>OazxHO+x<5|Ǿv*Wm_x{~-Glǽ͗4Gqtq>s9#q~H\Y^G_=k߆.;ACR/ \KJr<+w!(N]f#ؿMԮu{{ǰ8BM?wH?{nqoQf[v:WoM_]wGt87n8u2oEO7pjx -gpqoi̋N>r?v^YvPo\}6O_Lq4:>[|^/v {:z*Y?vWuܗN3Ny0z7o1KS|-m\~W0w)=>3^z|o]>vO)qj5uy^? ޛ2 ֍ /K8ܟ"1o_>A[/{WڷjKoWOoޣ>;mdG~?#4?c;ԫ >˴ %Ƴsut5KH}1} |z-"wWƇ;Cu8_ߐ#k9px{w>D&igSgUؗ3?&YCG빲'v+;ø9a!?%/}B_zOl~{AEHW@ٻU~֌|ϯW{>j_}-W딍HY{77~.ዞxz~o|f_s+ph F?uEG.,y5o.W~!w}Ml>T8wi ~&|x3Ϗ>='nvہsn|˞i|Fnԣy vuS{|O{E+CStsc.6'_%wk^ctn2 |\|ʼry2ϼOyq?ޑJI?NIqc4~<ԼeRNGG*p~M#/}؏yg&^#q5`gNGσ]O6z^-=߸ɝ}B~-pne7ҧ{;x/p6ȼޑWXԏyѸkN? ;P ﹤9)H4/ ~ OD>w3ot_?py{"ﹷqߒq\q nK)O >@+9.ɣ tK|/3?#y̳a ޭ_3_]Nߋ}ہ#O`ӾYq6㮽o.|] 's=ZG߆2鑟3šu)9{B~}w]e~`{}r<}^N#G=x2TVwG8د(}G~]߾=.bNiT~2ʇ̧f|ͣz+Cgs : ޝ};g޳8yv?H?boݏ ]ا[;ipϡ'#q5DEBe^[*M;=π^9~gŞ/?r[w;vG)gx67*L=_ݍH쎿O\|2Oĭg~F^ 7; ]u73o/~OiUq<*ȏ֧:g;ίsu 6ȿq~=^7?9APO韇^YeY[?z#}yYwГx= =3''zOɼjIwwpop^i>9z/TV]_ϴ~KiߐA60߁O/ݿ8>;gx8oqocUSNӸ_k 1Y g)3;8'άx͋{>z{G|Kϭ%?y |g/qd>f}.^z4xICyydiKk̇|z;?tTSqN_88 ?7y) ZztyWxg^H~A|e齃yFv3#~2yC<p+< Ѕ~*}884z_[Dz!`Ϸθ?;zO+Bo{K=4oW]Y/usz;|~Ȍ{FB+g؍>ٱ\W|_9<_Oͅjg1y,)9wXGy{`r= -a~@_WT??VBOáGqo,qۺ pymO<|/7/t;̃]qF-u8ygK_i|{~'rH{vu~|#_>C}ռ7kq4_zCGƅzoSjo?2^Co[qYG4v6 ecW*s(3>!{'#i~Y/W82 ~qp{6o5빊|)Q$]KRc'z~ȇ{!Eϛ_J)|oث|_|2C￑c_|+|7_C7Oq]%~}oa_;H}/{]~Oޤ}̼+Љg_K&w{"3846NyO_u,E۸D݋~~G3>hi#Gz`v1{R;j|s7 esoKO[VzZq+v^8nSzW2Wϋi3W|r޿Lr~2Bڿv^2>Kiv΍5~8KyZ3y>RrWJ(yޱ]px!qʴ>/xy!gݴ3ʹwܦ4Lug{{v+e|R]M;RW9sy=*evq2?/nn]:z-=𼍯2;+7NO?7'_"/љy/]yF?]ʻW|rt_/eG~ϼ'gR}ޚ:O~^89pgΞ?{>r^o+xp=;~g^/fw#Ϸ/fw.y CN^Ə.81oyn<{~3#QqS}:B 7&wk~xki/#zy~Hr&/O\ޑk??CWN3/?r=96xWyD?Hl>/vw~, ]:/} 7`_WL֙[;=GJ_v8 r:Wf~w2/xgϢ;v+:/|t98_<4pb|G*WG/9ws=]N/֞C~'x:e!7~y@״?W{Y(?v_yz eLc;|; {7g֕/dϮ'ԃ7zqKn8f?9E| +~V>uD^__go}zDW/>_:% AUg97C3߳dwx*gt=WߐxSp~"_?t}n;wƏr'헏g53ݗCG8u?rr+{/yfg?J A{i\:8;{pO/7]9~pu]u$~?Ae=Bn+C$&k^o|4ջƛo =_#gCz'Zou~Kg?'݁#w=qςi>Nf~p'Cy&jW'xχG..H{]Okv p?:w]>~Jx{ ^C՟:~ugw7.|B_J{Ky3x.ߟ~7t8n+#)xԏ_iHkGiqQh=>v!B %!'n~&|8?St( >$_[?9Nn߃nM9x#l#w>\6Avg~#_ \͗<ƣ_cGo;:i!B/|n3::kq g#|ɝ㞤)Ɓ;|l)36]Fݷp}Q|_7^yq'7Qy8̻ }7o{x?OB;qv~yR<[[\<YgQ G?79[y-{^+?GGk__K]>΃p-8/?+oƅwq(iy^kG5CLJyWrN~O6|V9:tSx#S>7)?tK:]z.W|9_jޜy/Jvy_>J4lK޳W=v|H =,xR 7:<sgOM7]jv?W;|лy|p9;L/>|۸z q)Ө?L;|8gCkM/x]hSyzy/%>~<>};p~wvOtvY]#/~3{ɔ9~=`|HNtQvK|~'.ȃ[_عN7W<]97? O7't ~YKe>{\-{<ΎF83v(ƃ=\7:?SwکFqf|O|n?xM;]P}r] BwJ=Zw~{L}q{3>l|>;߷qWH졎#97ίsjg}G#\{Gqg|ֻiDϐS^:#.#^\//=WߛW7ɉYMH;{zj| x}nWxU|?άF䏸]{r]g.qRw]Կo^Pn3G//sor4yC 3.ԏo]y^9U)ix|*GɧǯQ}k?՟=/<5yGD?i O^om=|_1rZ ^юyg\yN=z= !Q]S?c5/ t腞Orq&\Q/<u7D6(g$}8Ʊt9/p?z/Ncx G:nDk8xtݸqT.cB{= WNG9;~1k/ƃngpW5.= ʞ>V=i~Dܺ|gP+C.Cy ,}tni7WD|2}I9{_lo{]tGrqk5?CO{{ [~?çz#^IU7.# -8vDN=~ܫtw|~S<o!w={~?Uڱ?[=r ~4_y{Ǻ@w$/ZgqDL?Ƌ^Е+I=~/|霼K;{f||W/_5qG}(|6.|DPkEI8K|п}!t87xɼ{?5 9^(y)BN;j"/ tyb>? #wW7]c_\%/;rm><ԞCm>O{kW.GG?iQy7H!L `y|/~t݆>ϐKak|6pumԷI7> =f|sƓy0[u>>/_3ϞC?]~=9:_|WFV/̼vG^Vy{8@qowxo7qI?~$1pil#kǧ9ik<_ wRAo\Vڵy(90R;3nx~6΁oOc{6^|q]s533IoGgrM|M#7/A/~gïLgR;y'C^Ԯ6+;הl>|O~ |vo4.|}s?~ƿy`x>~r:ϼG4|G7'9rv-~q#͏uo|eA/ͫ{XuiӞoN60%SyO5_|{kT{(GJ?6;6Eiȭ3pYhzg73鹕o|0~{(C5pmrxR>?Յ'An'ld]ܬyNU9vg~Ɖt?&6l'tb|{'OS\ UYR8q|NMz>+_=#/]~ƙGOLw$'k{ey%<kN|}Ryn\]+vv{(x9-83Gy~KJ8~W{@)Ѽ= ?pj>t3q$Se~(wδ?iz<zy_9h96OWE|ޗg~";8CwGpJWj[t΍3+3ћ7 όCIOQ;у~L>MG?aM?Ox\)kqSjn 7ylgv|8_ ^ ݋y](G7WIgˁ|<>i{}"N;Rǧ>9.)2Nbډ)~2~6=1p\ ?_ڃׂ_W Ɨ Orə|9>G^",1kGNW2~r\x./|y{|>~0혿_Jy9]FOt|5|3^y9\>`?|5/;G@/Apwz#W;+n|13 n /uq;'I#x|`W?~%I3)}wloسG{+b<cB({~<%кaU+i^?BgGá{v;6QkSٸegͮG}Ď_կyfׁ;7;Km+)zǣ<ѱԝaG'%ebJr>xL? ?sse扞 2.]AǕOg{:5"Sx,|y[w_t5|Apzב3ciOE'9cyQ}~,'6oF(=?λOϼ ~iJNH[a\o;?˷yg!;um !oY?Et8OwBοYGk?WރxɁyٕimpJ?tfo c>y%'o!^3h%aOv@7%O{g=}g\u";?wэu"uxGt8޳)o7wH|mW;̟}qzӎuc?A|}*W?r2嫁ڏkf=ZzG :D[z}z<'<9y];>'Y_Sxׁ7g>k39/B.㞯wWvZ6~Co?igW)9HoW~<(7Eo/r#\^}}ib|b^k^J=߃7:OtHnw`GзqGD?+O~Jt^:Dʍy4me)^?S_y%/Lno)kq5aC3x?@#r;_gy~[q:ApWց٧/~:qLynH}xώ⇻'y)^?ؕ]|a>]W3tUNig~! >'"/o {O~qKtI ^=ux|/zE?|Cq1{vcc_C,ߔg>!q84|p4 Ë}W|6)կ|{z_<}zEg;|!!ß^|nl?ȼx?gvOi޷D7}S)w I'|@S)|v_<~/[f~oIO闟Yv}!477~r E~5?B?Tϔ8ټYh u>,zx:+9q[%D?O&ci|ڸ"r |댃w%KG;i3FN?ʹKN\~o3Ni>3;z}FCO~߸M!%{^#O?Ή4!ߓWH?*~# 0_p"W/.'򊞮'O vxB?|x!z\?G^~ӣ/;Hohb7g脾o7}n\}8]8;6:C/e<ߋy.Rک~W;Ʒ=JU:ܢoKs=LR 8oǟ8?zš_97ۑy>zRku/{3pe'{#<+q]1 \79.xJE{w>ߓ-:O@X\{,1'9J/Zes%{Ci#CU:\asYcoe~ ɳq{<߸w3:'ț~L=v÷ug}Ǟqxo!)]8o<O.? *طIr.A^qyoѝ_z~ri{ƏZڭ?? W71ƃJy-_b} 7.xWVbzOwe5 /W_rz^dݯユ|9|%DO<'lv7zqߨ,{>pƏgksOi?$kiiƃ9Qt% %t_[c~ ڸ| H >݇'of|gɑåԳsNaW=o~_n=r-rȫo>x=@ >_G<#8X9 'wBGo5wg~`깇Գ.; <7^,bG>S'߻—'o~j5s{_2/[k[{=A>~fAҟsčM) zt`uH9/>|u%5ߞ^i7&{=Cao7g/ ?Ӯ86F}q(O?:gl7W ~/+q1tϫ'ߑi!U=*S^Wp+^v!zv*9r\}>Ňn97#<\sڻ9n]xgȾ=אeXwt)gx&o}?pj<GÏ?c W*[N^!|R)^ɽ3ތёѫuƱg\x;k[GK byF/;z }O>×W><i<>{WE7Cv-L9^z9߿q~|>ώk_?#G|ԓO{LB7)e}s<%ħ#9g9OOiyS=O>7z~ə92J{?{ySfܷCGE>wN9q;i 0|M6=5^}0>YỴֿB#{ܬ;4'$?Qs7Ot=t(Eۺsu8B&I{v"}xeԗ=g)z_l~Kvzkm}ÜywS~iKkGp{~}yejg{h$7_p㸚$eQKY?~pk(r'U)k{tzIK(rk\pSOO ^+?n}Oѻ{a=?[k=Rc~/z^GY_~]~ٽ&oL4. =gyɓG>< >kMCG}.NOۏo*/_ž/r~u=E}@gk]_;ָGCDgN9z➿}_ {ͺM;cW#Orz qSG>Y~/:Jټx?Cx̸Mt~?V~e><`^I{-ɇͯey;~֏0ysG O78po+r'{OM?Ks~67xSO/Gߥ>Ϟbh^w}OF(>J3ٓ_޳s3G<9%|{{$z~ke7rSo~?eϯ/3/Qc1{g?NC\6<3w@GygG<8y8մy]ɋ)㽨|_lG Yl>0㶎bksc7=rH{|ظ"/ȿc]gίRv \ɁʍynyOo v[6oKLoS0?gmڿ?{*e~=?]̛^u+=9O ޛg r3GOwh}%C=}kk9g~߱KQ9<7Ny|9+|^AA]χ~wqyO.{S[#v#z{z]o)=/K~4J}e?y6>le ]6oeܞvQr}SUx{'*}TgZWXgwAƕ=__JA7|DG]=LY\g ^}=wӇ&ޞkO}ߑO]~`&O)Kioyz-<2j=k . Kys"5z>=/G]eEY;W{e)>||7NG&? 35>|Uyg\~a_7#{ W~K֑>Y^A/{4%WyFOyO \m͓T}L2ﵧ^#_^ccG~D3Myv?ߠ'z_ߟу~j<_γv멽w\g[ϙgyGo_gۇYd\LO_z?垗&2_-|D^UͿLGzIiBm_yÓs~|>1>EqVP붴q)ms3Ǐ?R̘7xΧg~x|~ƹyV럞j\]K5/k#IO~j_;{S}|/z<<{{Bw~|Ͼ@ugצ?o>s~zk‡M}p"|F3o?)o{t烼wks{~M9c \ӻg޳>}i?/i~tfvyȿKc+k=ON^P;b<qHG7r9kG=͇.{(/sKWͮt'R_A/w{Roq=o n/y8>=?!;>={7/C'/ Kt Ko? ?wGQYfG|߅D>7SH^ySf?^bSvVn[]=^"go>홙W<^9tu]ow#/>9ǧ W{vO\1/ߙ񰯭е~/l)ůw?=_zPzs܃\3IS}sԯ~:̳GF7^֫jhھq=}7ҥ}G/KA)k̷q ~Ay>9@p'OC{^l̷ag40\#ޛ '鏝K#_2ύp'߭/x~Tz+^{^^ ߚ⯑s_]l~}4~}Bnm>YO 2ϼSy/E㩿"ޑvE'Zӫs~ܺ<i%5u:G`Oys~dr^q8̓<7.<ȽH53B}bg}j݈/Q{6Ɠzd~dn(4>l^O.6'iMfzbm|)oR)#o.c_ĺy?_<}ݽ7jOcmkdww3(]y_^pPރajM6v;j 9߱噋7r %u4HO\Dbϸ6=b?~ޣ~[irrxX5p?O/:{Տ;cyO?>;zw?rƙʗw5X:Gi;v!Eoz[J~O8wq_W)ۋww!y6k o+{]+z3o'8K]ޣD>84-MgyC.vҮ]=|"O;'듔q\\ƥGGlt|KI+|M~7a5ӯy4NkIsm)7 \_YW67^8\zO^ >ە+7{qq9cܞ~Li|ss<{yxEVuĿvgތw}Oww~NC{vk2/}oơx|gѼ}vqG7-{юPq^ޒ=_CnqB5xSzJn*:2~r RϜZ{t}qorvߗx$%Y?"|M}CGN{Q9xO['G=v߾q)/ 6|!z!+~>??%}~p4>A/l~y쌣6tgv;yX{vk7?[x t}| ~q~R9p=?o B'5G`}ObyZ{G|>OŤ>m~h֑^EgD঴k^O=~.+ڸfyفo|vC'rǸ?7)ŃY779UW5o =?1?cy&O5? :Fgn6{W;ѼAw8~jsg~H7rٕOonMㆧ|~/~4|vڭ_hQiqS)7^4]xyݮ3zǯR/@Tsw Y?)W7 N;7JpO}H~_|s CpM{>l$y|B3_:Ji]W#goUXߓ=lx/H> ?Ưiyo#OۺGy۸ȏ=/:+1_ \*_8_M=qt_4o?$y(ɭTig ybK_O5+^ƣ^ʯ<?'ߙNo>ϕ?ޞoIaP-Xt¿gq)ꑼg?:xegA<7%;%y7>3'L?2{6K w~pKI^{a߭VyiXv?xib]7I!%;d5/ |_ z{f|>j[3rٛbh_[SOX4oon}Qs'6o>]`%'{yk~ⴏk\yŮ oؓ?O!9>_tN?5w| ƕzˁ.zn\K{7gv3ؼ7:,qx#wQ5AϻorMϕ9y_|Xgp{mFne1s6q?xclr37o);QA׽|_t||m}9vYm`w}0v|mc_?X;{FyOkx^FN4.Gьzk㯼;?{-wiFt9Ǥs; \{}@yF~uI=i|qzyUJx]#ǗOHi]Ot_"_z(ϗF>s?Aoo~yj 73ow9֫g7ٳWJv2|l>UJ>xWAN Ỵƹk/>{NWI|x;h7q#oy/ ߔz׼$y~zb^SO^yKaKMq/2t|kKy~j7e]O~"w[zvA?Z'nsjo}vVkh~oz[{YRt9@_։='z٣Gn29SʯGiaߍTyy뗞"O?jWdn]7,(?s`yf<C/zn||?yR;ntӸs*yOïqz߼k/ފ/s\ROaX7Oeoߡhg\E?TwuyL;r+Ѵ0obyg/zɯjiQ{~A~@ks׵g{I7]:w} 7><阮߯Ns;~\xc7Y?C;?D~ x+q#=j|DGSy*3naG qo?zj^&py1F> s^/Sɝߛ׿ ?m ϞS3CEL=zJ=/t|}ޓc+{nx6~|g|{^>oezIQ#8V@H+K#MZKMH^&<~3ʘz& _2fI2 {~Ի[A OzT.V[ZUH;Y{SB8ߤO7k.vO{9v)_ѸsOߍN{>>6?sUt8{j;/d ~?wA{Ji{'O =RrejJZ}=!N.Mڵk}oL9?yLyc/e{'S]\_ꁧ߂>W{Otޓg]݇wy}ˍC?d {yy3x;=o7ظCk /;?US@'wK\=_ ~w" = W")fp{O/^m9~h /?Q{Ol@2_̻ƃO#r-C3nϣ RBgșЇ9 %O܃C>wonRj\=ydwwLo?~^)qA~fb%8%N"׸=jo__?1呓O}_O_SGS떔}7;+;)csI{A%^uw1xyQƝduI3]'$m|~}>RύNoRؤ=&m|;vH 9x|GG}f>K΅ziyX#xbMt߬|^o~7H;#@!OUN 㤎d)t\O+>l"X^C.(r)>tߡw+~lqE~ȣƏj>Uw OH1~}]i<H.#~784>ڏ\gow}DnbOW>wǼ{~P>DB)"z}-z. n+~gκg!b<zBxv\{weމ)_c\SA ޻@?[8z~& Ns ]|G_4N~^RqcޠnA^gzW=x|B nǢ6%^TWs]޿ 7O_BNU?I9^*bWPya_ >-?v2½]|]]/B/)Znѻy zz]~*ߐ?/v<KWث֛e~/F9{)?*t)y}*e?/7"ߜ#IDOCOܻߙݡww;+~=K÷/o\,{Qggv~%{qZo:e>?Ji {m{ 9i9|1AE~r><՞O =3zV$ 3%_P9 ̸|OnO}?:Nf]_3ߥ申z{n+ g5vj?;~\Y/\Ko|=ッ|=^oDz :N*)yOr=|'`qw~'$ORhE7![-о E4){,߁sSV|}C{zDR-N o~{+zSzsDn2)ǾXϛt}W^?g}wR?oT NkYtr~ޏ^Ň뽣'boýAqOA ~Bϰ.AOJ}Ǎ!Ϙ}}}5ϻzzTz()b@ƹݯ{]i +ߔC"}oZ|NIFW1r|&O<݄΀ݷJ{Ѓ4xh[?S͋Y78 | pSu7G|^h ߎ,2շ{X{Cc_A.ԏ v/n<_:a{S!/5n=.iQ7?-^||ϋ\7_D|Zr&yd'>oTw >zQ%얾!g75^XWv-yx?oy8H^`9^J.<'ba_g][G t8Nߑ)'P|¼_rxY_^Q~o;~9qeޯb'Ct'2з,M_Awɳv>WG}^oAy08/z}w ~c=; =n_~a]U)wC'ɣokt߅D~sc"*9їєg>zNq%$7~\=W+_/>w?D)=xOW/ ;_i諟N|SNFnߜc_=y\NN9On|[E?OWzDCo?y߭[8 }UDszA{*7x{彯-rM_{؇ۼg=rl<ϝބ_ӏmxJtIAƋ<™qt#|؞r ?~z^AMG+grc%rLQ9|ϠOcsk1CrǾi $/cy87^?/( M_xnL^'ImqgOgM/Uo$oyq9ެ?6_wӅ孷dzI$eW7ɁOF;ۉ.ԫJPpLv,gi~Ni +ӱlr֗詟<.?'9bybP:xi}U{fm>Ӽw4?y? sͦwOhޭ›]E3{ޞ-6ukk?cy;лjhoNӹbZz7țnk Oi?K.{ |U mo~y|~/1M>U?[~kѯ~r3rQ3OMߔ+^>k{~ͫSո-׬6ew$<=|qOu8مG/0}m|7[x#?h牏,/y>qsCyuMO'yc_d9Auh ދ>o~jdo1n˙&:]u߰S5ӽO|ȥ}7\k֣и&?rh j{7f'MO:s_߹DP>4^:x<\=Kq[ӓ6lMjS\gˍɎqyww{uch?c~6+:ؾۃ[Yڧ?ڙcG5_; JQ]-[?KdOx &DcZ'/sg6`.[xw[oXN dsf.>9G\\N7t,9}IO~tNύ~"ünƃNJv2g}\§&mqg:>~S$xi} Ƕ!z@M~֦/DwSܒ %JggƟxMc>~AoANOި/~1:h =}\i>tqx ;lqG>$.g$K/lp0n֗%>ٝﴯp}Ǐ'=?nfj[ ^/^dOS< ~6ߌ &֥=a<<1L9^gֳ4o0՞CAMrpnit[rx'~$Wq?Eutn>R\B~&w%lML3_x0MGpn%[|]?T ? G?tɏ 㾉i_}:x'kGzcw䗜kӹImL)uǷz ?q:5Nϧle98eoɞ;o3|b4]L4$&ysQ.jK=ϴ?9~{Ƶѡ\F7{_q;SdN)>I=EBɏm&&`Mpn)n3Npɿn~97m4(?) '7L ovoKxk<1o [l<MS\;ӝ/][_Mvo~,|22k>Fx?DxMc{vzeQ ? ,ܿǽ ԟO0mLzoߍ~Rkwth}?L\'8&4';`\[ 3H灏'lZ^l'a?m{p]ÛN,]LtjNq㶮_ѕG9❓nOizb߅/lI5/cD[#q~m=' ץ5/g?9i<ӹ9 Oϱ4/ lorOx]777_ܦWKrntpɏ7уrLZqmm ﶫ?~g^eZwm~[5=soqj~~W3Kr~Z[mtt?h x_])0><ƨo:̯k2 c_\ƿ 7?0KƁ1)&vXqcaR;ϛP'=ripZ?]j?s~K2CG>:r:5mMqW<͋_O)k4 nd`^Ӻ߈Һ}ZN~i?w|~ [>{G?yKii{ݽ[{~^zg6h޶8ƤexڡO{?wHH)g![lv渟+:~;wuN.~%"z_qH/rΌ7 _;,_|B?~?smv^Utg]3lzG=㷽%Lt3ﶏ37޷4.xzΪE|p0>~~4ޏc צǕ|~u{cK~ʝWFl:hLfi.o>Η񳻼 ܝ'cGoC׶|un0cG+VnoflqbO]5AN<Ro=X6nCv :o)fl>LGfwom~iO>n=izOx|y6lЄq}>U>M/t =xnf'ߌvƳI,?L~^OAs䟚6N_d:@;lל7sg!?3?k{tϪi/ֿa_;й~Bqs96rbkl ~I&r#LOig<ԟAMe;tz|zv϶4&'p;Uo}?~\G^ovsj~M ivv䀯)`)e_~nGھ ϖc3_:.݇*? ,G,=g`|EO~mXy{-&؇?Aؾ ݏw&yyij>;4#>xO׾E?]ljNH,oHrsܟ.9'8=^ϏgՎe1M;5^1?6״:i_} LrlqCtg?2mWpLr|~|ҹߒr@{2=o͞]zkMzf/G1O0i;~7>UO~m#97?nq6dGA_X\:4osZny1ųl˛NG/șis9^&:qZlJ{H@qzg[䧙Lr{3~nY`ilKaJӧ׭}|/^/ǖӾaܗ޽hxi&9~}D>9z1vF]/0CzOxRa6 _/oޟU'x|'>)iۧ4NvzuZLq4n~ǵS^fzvuoK㰞? 8'?<ظ?4/96981W1yѥs].yF󴭟͟\`;{Ϳ1}i_bZϏt1ޟyWݸӆy7]?i>^&'8毻 &O}|uC0zXLpv?;\~/zTt9gOö (쿡ݯc{WrAk_{_5&kd{xkNcElAxoko;ۥ{6a)iI׉^G~6M{??sjݬcדWCa+'8ɯ1Xz5-M,8u^?re9'OEϗm_?&ǔsfp|or7s?Zm߃z?Mkc0 Zn7>wgM|pOW{S4ե8=ߴI0ѹb"|rip\Mr_Fo3ͯL96ɕɿqzc;2DgzA^?'u[ݍ4O:E>:QkW~He8|~n{MSut6z_a-~/KL7tD9Kc? a>D}cc$=S<Bt>{̇<=L5\c?ӾgmC[?v;_|Rztm%8|v7N0Nr}Z/Lqb֣Ӿ>G?wEG]N2ťLֶ:x<죞~~addol넁m;`)u´1&y%x'vSdZNGC}Ѡ4>oÏמ-Btӻ)7o'Ds-AMq+:x5}LfOoi'9a{k0xKo]8f'[YLxdg_P!#Ldž0̧y|b?uᆿ8)陉&9QDO0y[MqӾǶ;٣-Njf ~r;g}AXy8&&[tɾk׉^S#y;f<]0Ӽ_[<}K9Kqu߭_>m5=tԓ a7:>geB~ /uOrt;?H׃qN.S;cW7bo2~w<=P~7|&:zS&WK\a|SҸ>S+2죋睅M.'Oa˚ϕtqaz~Nb3Зxӽ0۶8K>ݻ;ş~JPoovS&?CMW$G?y~{~ԟ|`;~ϴgxߥ{>R;oo֡||Nv;մttj=3ūL/d?L$7c8K擉.yؓ:юm3ȣ֏S\ҶN5.xC'ˉ7?ߴ=Sii5{C_hÁ.Ƹ>Ӌh rc'Gaw^u+{\Z@/1]nx5HnOx1p}tI !zQ7.E1߉uFwjg#7فk|ݯ7#>'ӹoLmރONv$-5eKi>63^ G?gjw?Ҿߖ/᫟,?w:ayq~_~'}6ٟaڝ uvoڟ4>&~&t~#ÓD8'_\ү7~RIiGItyI/??acƛv|8ˁ+\Txy~ϣ;yҧ ?~+Bo5 b)Bo|= <3#ढ़|Ͼ4rQү&/)xb~or/ׯTjG=_}!Gg?ϿJ ɿ~q;r@rxg~X_BG;FB_ӯ]|#yzv; NjORbڭ7x3o7W?yO7^K}G>2:3I'Y{+mEa2Kwy">GoOz|~o=G~7$pZn3N?;O#K+ KY/tyh9}=r+>} ؟w#ߙwt~< xF2=6SBvvK x!C΍A_[ ]2G)3__QRQ۴'_Vܭn=|`z~k`ڃR p~;+#K:2+KIӧ+$xg9yw ףS|$2>$2NlGJoՓ^rj_?xj K$a#tNo^^SrR/TNg\ |>H_RiƉO8呗ro5Im[M]&_GK|G.K9[톤r9<`>o{v?)qW,ŋ辒HI9uM| HP9迯)ۇ"g凤1|g^ t~#I}9|' -םKת"Oȍkkz7i##r:GP|@=}o׏wk{-?#)E;q߮_ ~Cc1}md=_;:W>^㆟>C{)_:>2|]z>r߭?'Ͼ|1WSMSyBny T~4|oZ]FF^!g_ <'7xL59|7NƏI׿j>|9iq0#\G|}:K}zͳdi|MտI979xkq>8W4v}15w gq2_[5ꏾR>= ؗeN)|x_+r/ȹ?%Xc?5nmDn䱃T3+R攲g_B 3|3͞z1屻4~|NGq4i_w՟]]/;Ϸs}(XS$~'GO^Ol>/7Gz:>?ַa~|. xk9d{vuyHoɣQվAׄo2]ַ/ݞ껤~R'ݑR?:n g =g|ȫ]`Gqտ+/ve?D⸦5;zRI~KpCL)8~Ic+&ܟRC"iH}䱧+/a5" 9(rqJu^v$Kr @t<xw-|)g޸|GO/=)O| I> Oyޟ%=)qY ")v/v N?֏8k''+Bn3w't>.=d\_y^i^F=IƍZo_cXG$+v SFRz/+nOk|Hʓ r;?xANO}\b߅} xzqakWCW "Л0_K#qk ھg^|'85_ŸG. tƾe|mxO;􋼁Oa/@O3N7Oƛ$/빠GH ]#CF'I||R樯SH^wt.ߙ  wEޱO8|}մ;i:+{v~z~$)WixrsJGnk^Q;]/c+I3|qЭυ;T\W#<9y7]"iwk{?8p}+?~yB:HkxSA/ic3߯)e: ۼ]DɃw◠9]=A;j&~ZWIh^7@=q\?sŇ~FvDgmbR~7}S?_H@?GoWCo9ry<>G^?v$B+:~S3n~]Ey_{ח5Ӏ7faB5QMy#B7~kvyuϧ]p~>'~Uvf{8m@s{J#>qr;?Hyv@lxET_$/奴}g{?M=s<7'|CNX[>vxMٿ~y!xк3ߧ=gI?W}v=Xy#S%N5|)|Z` ToʷːMʸ ?/#~z=ulcúڣu.{=OcGAKݣHOg_y۟>A:SysV{I[`P<%Mlw#8'8qm"_g}\75)y'7;{[}>|r_f|)׸=aX ]uD꽨ZyD^|N}E^{~\'Sm\`@(=yF/OɳS{ K~H;!| 7NDO=6ȯKWcկra'~#wo>g=<|9p2ޫS ?Z:L;7ɳ_}&7tEq2[gsqIe:ΪPi|qsJ Iӹ'f>y;ri)mWBTDn0Iqk}痻H}ƞ&E_8/xANgRJhWc^#|ggZy#ox^Co<>灿[i:e_;z 8J7y5rq@O/uk-|eg,8? r{Xǃ՞SIg_Kck[4n=߉ðnBzoF8U;{2}:u/@ߍ7JGW+|)qi>s I\=O+<+oqIF^^'~?C9]{+{ cvlosXw}g^cǿurq%sG?c*0N~.'J{ݱ/iR]{zMSRP8|o-Xq"0G{tZ-z/qOo}6o#ypۯL }^+t~-^9g{p6ڟ8|_QG~ ϻQWk=ӀcЯը+&ʩ>M} ==7<>wuC;~q{+^𨿾r|Os=Q}\mB򾯭+}^R8;$;Ɠ'ubF.|38ooo>z5|>vRO~o<:ݞ?v̿Q{w.~[O< /'~'x# FtqOzߑ?}xeǎOL@/'*GJ=#z󢜣ߓGq"G_=krzrfspn$A>zsJmߋ ޠ'==w{I{Bʽbs\C?+}Y}! Igz>pܚX)stߤ '#<h'{@ʱr:3θcJ|:{?Vڱ~鹚 x.?|{RNҞ3^NO?lpW9G'OzCV}Hy煴~ynI?B[ߣIZ{juRƥqAH/}UГ{|Σ{{m|n-8}%c^l~~/iU9(nC~.zhßߩ=;\JF4&V;|/s~qެ^H>.~b=,,]Jy֧'VxW=}7!),̇5AO>þJ~ITy'ot'M)"?{gO b|^nU >'7 {>0ߑ{=yS>:{|G~Դs~}vvgb?p!YQ/i7{)R=,zls>{Ӿ#o_*SV/mzn&큇kq#W=Ӹ[;.(_C^׿v> *v3zU߿Sܠky;NC> +wU':y4K7{9 =u6.&੟2){G.vvoYR'O7y/$yӒv'M)"g: ޾sg~oH㘒~j>;/[a;bݱڒg z?CҞOHy'5}#?{ vac<|].|{rݷޟb={}cvg'3+`Xa]s~\0|JzqGげBĻ&|M{ Ozq),>?rXÿ>=Sxa|ƣ7T9.*z_MRx\?nQzOHgLy/`g?ɥS8jz~=+~tV=gqn3m?{9q,| g~ qR3{ڮͭfo#96s%E/xi/B. WݷH9w/ 1p g|c|}3d}݋>H}vSWy!)z#q1o q =_z;r 8z.?wnȽcL /}/'/ڏN)L^=k^} ~M)=zo`vJO97)%SȻvqz4/)tB̯Ewzzqm3]q>]z>/=ϑ/v^')Bn﹝||9:?3WxkxF?MSՕgq1M;K8t^S[@nznS?ym=7L78ƍ~:iRkݭ3.)6>zGG^#k_~Y_I}g~oB#W9yvE=Z?6t=D|̓w?[˝ԯ]-zo7w`˪߯?ty$7CLJn{>xޫ;}~5.~[LXr}w cK~}彟]=OJeoO}oN7i/k{ڗ\Dbc0'cwXN|EcAb'=M>WAyɳg_ R֏'C83 3}פn~|㸎V~Ӧ^kʟC;e/%)~d~1)"M{ou밎723RO{!7~jM{-yCxz.QFy ){uqwkfg{FkțoO*)t},o8˥r+"/]S^ F{#~H W K}+)5ŗlqfpR8ԃ^Ty{C}gb?yh g3.Ke]>t3{% :+J9u,C ?wmAk<؅~n򍻸[Dž2N}cOgOx~ ri>ʡgώl|HR\$hy3~ʧc3|*NL긁?Zǿc^Q~G]_zz\&z<'}) mZ ~þCA{{M|㘎kg=<|κ }oI=I .yN.붮zW_3or70sHYOo|bEuɳLrߞzK??lo^ǽizCPs ^}_=Lic/{Fa}s;Hn_ϟQ9q!i8qo5Y#Xw?JQn Lʁ'')_v 71~ac|Yp_ F~1\NCy6n~^q\/mz?}RK}-zSW^c]}Yg\IF_IgYWiOFQ~RO?vηnO)qGL`׼r|?=?yX8l<@ <70y5HGo܁ק,ߧqQs\Cw=~u\5"YL:?q}vI9M9sIY3/>abG㬏knaN'7븎d}@N{O—bۗЙ1oqܮϛZe~}Ω087 {Oqf&+\OU/kW)sJ![ʣ|?8ػS)ře.?ۏu!W=wo;̗U=ojg1d|r?Jha)ԾZ%7*S>J_'2 cyT^ |x9y|w2S#zھߋ=܇* 8뵟G*}uOճߑ v!:W6^8_v ޿|G|Kp߫Ӱs,]v_5wnM{s=f܌Sq w?7{OIR ^{n7wL{ݏM)x ρqތ3CRz${nKcgw̸(G?c]\=w+U^^<싔.}_\;߱|q2/ȁk9{VO:'vRk[zg}q:Nv*mSZ;p0-ߑ{˵'Sp|ܺЭ{>6L}vѻ^VN픴sK|BOt}|::߱࿞C}H89y\o)e?|>U}{W<> \^^LʼJ)]ew>> juv[5>X*IZqgOS=IŻܬ_gH=R]8LSt]&pk>a-?zOY?cw`}>G={W6pQN/?ݯw~?4~E> a?xz/ c\ɳ{@+;S?߻_q3&{?AOCgC@.#6wQ?p ``cr3G @?K1)|xL?Wyv6:[ w_9)T.Auﴗ|S?}z~v _co.o|B}Nv5>ޟqhݏw "^J}+)v󈞃W/Gz}>::}}ǁzG+<F˯礟N׸4թϺqG|#?=Ywt˞?A[a3nvlםG<@oկ|}K93X7!<{|*V.:~ |MSp\q_WּxܞRˡʫ%a/G_Nڻ[zDUO]z2 a7|}Ǣw'r@[ma4a}aF'g8Suc#6-)xrܤ}~”c_O[]qGWkӴ{͓I5LSݔsu<~w~_qg=+z?CB\WW>I9 ?tθ'r zbq؟Yge_Or谶4Zqݓ{AP/p!ggN!ű57r|/R\/wW=CgWLnq6=\RyոSs>|>.}_A"Bދw%]H=QXc' ︯o#HoI{]Q߇K _R?s?K)E=bݭ.Iy'xDϼn~}ƉIS7LJIt:ٰ׸ke<wzC5_{=)x"弯{ FQ{|0^:N~#Y߆_ا+qu_j}T|`ZPgݛO)sc'8GW#| #M#șq?O DI}og|CIܜ}}g䒯^7^%)x?WyvDWv;ܭ6帎}0?9%S<+}V}/^SSwnN黩F{3p۩O_Zi?N)mׂ7~I{oqgy?I׀/Riͽo{IymJiTSAA/I8J}n{7|ޝ?NʽvN g|kk{p8_n{y/:ηR}>?|eZ~|m8)wNCk<ϭ〞'|Cziɥgہ #>ya;i./_)go"ݽ1-H?xE@oENTާ}Ɲ)_K+~w? GO~+> #oa^KzBPyo_<qD~.\+/WG.A/W{a3c]y~pq2޻]9g]vzݮ깔?YotzrC =:^Iy~OS_tY8wk9ګy|~78sAzz]OIC9[wk;u-]f?Ҟyy#~RmN“zY_>;ʁCßkI~ǻܬ`C?OnW8􏾪۵ [s]'Ry]7̸@]=;o?7-~-C>uŸﻁ ^ᅟя鶮tz_k.|M>?1\ = ig?ȃ۵~_Dok#}4x@_r~+Nz"?f=&}-@2Wyzy+?Z=~-p"-p:O 㳾>xouW1P_:|y]zCFBFxi7"OkO"?SO~>Vw!r^[׻v Q9'r Ôz Iױ_k'knWYgvvGiIY5z?N?]??A;{tѳ#=irF+pg[TyzHSKʧM[kgfqm/w^>Z6pǎ@/؏w1X{!#G~U= Of>v ir8SVe^O=:R3svE ? ؟쟢w~ٿz[|w'XNk]#XwoAz*OSe@9> v#}9?aWWחi~G೼+ǻq2|/wܩ"W z~C d]n}{M}R91nGC~8VwxC㪟;g3GM/276^o~7?}Y{vGaSm|$ =yﴷU?'e WR[ Щ zq祿;vMJi~¾D Sj:6xi+|#Ocaúx9Q7(@imqǴ<3v~l.>~nY_Sux)Wruiľ~t>z?6wzN>s/X}?SmC.~ }cO09m /פiy3vor_b)e? C\/eް:i;y3m|hh[}Hޯviq?2 /N.^ pmy_J_>07wq]; Y ۵ ?Ǔz_'7͸ă+8 xYAkfT鏟^x#o}r(p_?wʋ o?r~֔>/[=?pg)g?~;[1y~}x, ^ȳ%ߨ}{ک[=wᾧ|ܹvuDi/_=8w_ꣵ\b}6v# <+r: y}gGZ>t^PB>e>xv}V{i~<v—r_;Y_inu,vsv"2껃_oq\L|_}zywT>k俍5~rFj\vxSqڙ+3v}1/~tY<]|}ێg`+J)o|j']rdȿeߥp6^<۞h-~x];{>wrSLa g|>z^=pOm|q(q7o9]&Sl:Lƕ>׸ϿI칍{>3sbNoiN=\X_5ύrq\k-|tkϿ}M7zr,㮝8I]q:A7OyvdGv3<^ئN^2B)_}2Tx`s+u޷ޞ4s^W1Ky~N3^tQ<<{k {ƙu: PɌ׺zWY+/vJ~f>:qMZR.)pw߆q-G#ه|i絛þc_c'C_ڭ侵Zxz [|YץNቜI/e\خzGQt||[_=E}+GQ?h>7nStqwbuy_XOdǁ}}_/a9?Ɲ~WhxݙzVly_~`A\HŷK5@g)Gߣ_o?OCxםܘ/~y~G<؟NCwk݁qOlik^,4~ _ݳq'y[H;=~$m_j=7ߞM}}5?8+Yus|kI{; nlG>>I~px;+c>OK叧x`?5>&e YAg|Z;݌뭓3q^xcO^h׺Jk3Rk/z"G#^Cx_wk<^8~kO9H. d_ϡlҾyH2Es/y̯NyN73OǮϓu+pwS!izZm8vx7+Gw8:e@>ωϡ79C?s'OzS1ԯ2oa['#p\L[x; '_<ɸ/89y$NC1Y~oK;=wBL> ~u|ݗZ˳zdݿ31xJjx*qt <|_;u\G2t>fAy^i/G5>_|_ƙ~j_iW۝tni+?ۮ|Gk9|O^׾=ƓcgJ'n+GI91ΞgOGk?NCK^c^uxeJqMfCgs{~|+uHEggr OBnJo kJ=7xg^w>sM?~Nuz^vVS?؄7_sgX'O~+;G.c߃ug ͣ4{yW^MGky.N(}vpc?i_Џ{vsܦ^7>ƕ+튫mԯt?|ώj|x7j7{o n~38?U؟sx'kON->˸}{qiqs9)!fshmO/sw}v#-ҫDG >ߟ=ؼp{f埃NwO|aO4X` >x~ 7߭~ً'yϓ9{> ͸f\}cݼO {to]ctlzkg|1cQ@o:<wr{>K}_~7*u?ow<ǺjGq:Iw3 >zNYʸ_(AG]U7~R{~ ?<sxkc5<+\阯M+8{ڟo8zyȗsg< _o=~6Zs1z~.7ܼ3u^N?^8OKik' <ݯI}Y7hʡ/<{zo7F##I(nco1o_k[r혟x'OCYxpSO|Cڥ6v2=Ǵk}4NݠCG}Io_vmow{<:j>dH/o\⮺N3S~w}:uQqOӟ<#WO7X{.;8Ob~g?O;[yL]ojtG7cwSzj>CxO~?6zV 7hŇyEWފwv_Rnu>-=7f}xxkI{=^>9^=Ɨ6?\JiކSg9hsig_$I{/y~OEog K|X\z=K|p<πe?>m;{.3ƝQzV||vC>yW~]: Yhuh/g~r~gp-̣gi筁:͛鏽ռۃ>O.w{u\c~4%/ãC:Y/<8})7)Mq'<˿[Oн?#4qp]ym<3>|]G>?z '8'OR^vƙy7y6u(iFu>Z^ϥv}u/yl؝IxexgrAsgnj}>+Gq4 4`CݯJ;yyOBqʡs~ЙqqbYgvw8f+w9w1_OwΏ8|o^|oky|ӧ{~w_mv'Vz8R?Ovc#ׯ<Oz9z]wJa<:~qVAxY#ǟ 8f^ 66lS.tm]8KGIɃO_xŏX9CghFf.kd}cg_M?8(y>"ޫvf>F|ByۼN>M8۽kaơݔÿ{ ~yzduqȋ3GhOs^J?Fvyssk97li~)xGyo>ytr{k6Ns8ןz ?j?}Y>_#|=m۟sLoS~ƭOlގ7g'+wMh,k +ow~q}ypwנM /w?|R8?]pWept_*rlڟOy?v|xdkMN^D]3ɯOoO)W0~u~ǟwʱ7ڏ}_<#yHng >v5}l|s7i#y/=Vqϼ|zx!=N7]gƇsnC9{gW;ֽySgry|%OəUowx9I{Y~/ qnv{&kwg>4>]I;Y Gpw~}-.52/=Y;q{ֿ~ztw:o\aڕoޤG'a (5r#聽tm'=W/>b|xOt/|-x/,snJ=PrS?y{Sk_^ssQo$?wq|P%/햿{|n7_{Ny{7y<>)g?i/ppK]ǁYO=읜W?]ާg؁/oe_;{䝔?yOGYP}yk}~i/:?+}򏚿Ǻ}2x)_zy^|μh\ <8iv}k Gq{}c<+Rܷ>/3'w0]Y^syy!?j/j>\ :~{Q/7?N,`ϒz#7Sk]Ywqr"pWg"5oހFiqֽ~}y9~?Zsq[yGZ$w^YO/{9M?_F7|>i+\zʷ!WS ;5O=W{n3>r@'Pf^1Nj|wOWON/gZϙGg}'99:k(яQoEwm>q=~S_7W f^Qy~'E ޛ_Z/WySNW8w QA~V}vx^Wwhn7!>8oxzo.ؾ {yZ^oz7_~cY۵Ji|2t)E}nzςzyV \}q6N= ~H <>=vh=Kk\z_AwzVBڅـ%i?7?Z>ƿA#i7ҏ&>io]>{φog;Zf|^<Տ N̸2 ߝѣwxGN :ޫȻQ}c27/JgO>wgɿ+~ynl2W%+w{t!x[>o=qj}\s7rSiG7oSvt:R\ъGf̸ Fvɇ[o߸AcO9|L8O ^OG7z8!''N3m)ÿqj/{{myz<|e/SEg{WߦոڌUH{G8Ǽ̳p7摿m浺wx׼4~ /[}?ZZzݷ1zjy2?bck~oc>yԙM+hA/9ԯ߆|/x><^.pE/g?yռ6D{yK? n=zؓ=WY*p߾zQ؛Ӵy!;z<;k Vk㿻~ ^혿鏪+M=b{!}s)g_yҿz:OvM1[>mn_鮝ݫ<Y_ϵOvz 8'`?ڴJ^Jڧ_sz0~\/~|<ɳk^g=oy?MFRnokYsrw}7oOgXy54K( O^?k}]t߭G{J^5ϟ_~>L?v/'+~ã78 9w|߹IOzc_+ަ_ɳż׸ K}錻 {O*f܌=OF>[;~KWG rO=}>qgi^5Yڵ.øc}Cy_=~x>m3{Xguq 9[ȸ'7ki35'+~~G< y2N|)]~Oo>4$ߛ98orW;͛8.D'v*:M 'zS}=ziʟ[Fވ=u='z_ȃu̫q~g7t#{OwƗglW>/8ry'RGYρv_^zjQp\h%Oć޳js󃄾/}:<"|fs|=TO8))|vTRy^ y,fmqś~;^zqq;]˃W/r{6UaU=w¾0Q;2No^ |kO^觍KKhxz{x\yz=]銇KyF]\kq>ɕ+Og'zc3ys~v39Կ=ywz< ,;޴t ܕ[^vT4?[+7no?K}z{J~.|~|x+J˒q?|Nʣ'~xG4Woׂ׼0zlRUA[ϳ[yiL}ʏ;_X~~W=d{6N-'_ԯrqGgsnv?~8٩>͎S~Axʞ+qM=toT{3ߧk;g$qƑz |zz<;?W{ސs ݞ|=Z}*>/[s8C{4r1wƅCq'ѧxn;gwX}tɏ}lIi~׸ԯ=y+{xrkS>8zn!ZY~ =^-z9[Njt8yN{&ָ7tsyϥyލ|;anߡ|V\ƽs)g{{ZNwOzMqR>s>Ӟ8o_lz3=s{ʋ[}D^=HǣG;)N~.vL}.o? ^;W(S_9ʿO_Ŀ{{{{eO7g(C4ɓ<8Oݳ=yr~oI}nW?;1pGk{W#{~`֛qg^ߑz ]?K_M{?x=)G/Cꝧ+<ͯ>7oqyzn6鹻bἯ'nݟr =zB?>m}{~5Ѹ '<<V|MͣvӞ3׫t7?_]O[{?5~<'y?=űk' ][ĺG5vOn`'Oy8Os[?Wćg??~gލJ=W|HyV/?Sym;}qi?ywovO~w}6hیj~mڝ~7voz罐ʹih qzDJR޼7?8hct} ڡߤW}<__knG3<~a<[z|>vHrj^<w}u૝ϴk?Ѻ}n}Gy/ޝWԮt)GnzRn3z_Cxٞp|o}_: ~jToݵ\o]t{2.󑾿/S_>nqi׎{Zvmp=~5x1埅܏Z'ƥ|:D7jJuog׳cAǏՌIr<=\ _+~9\H+'~%g{ew73ˡ ܯߵz2χ?_K'zs?>p]_Oޟ=|+}'y|.?y!~'q=:yfCrXhڵ~/fCۻvnccoRZ~/CyCOYm%b~q>~_}&tMz0 KG~_:wtn// noy~G@y>B3N~kχ :/dr*~K^x}O|!_\ <_SG|?xo5_8M=舾eX7Ox>AgO8^b~/_п+c+Ky''ϡ>xҿu9|џ{.WBn=LO?i[K+OvDOϥ5|#C:3kAwI=z΋H}6O~W{=|s^~Jo @O֮dSܾ~ًo>ٸ3x!oj:dO .g/SS{㕎<;' ?qg?oy&\g}|&<o<3=r_߃GW?XK8襏x?FO'+z^f{˺ ]y$蕕sfב;&?Og2>[ ?;:|4ѯ唿#_zy+?p[>LӃ#iu.y^<=zڣǼ[^W~_oV/S6ۺJ?_Nǭߔȍ̀bWmO{/v L}_ \O<}\;:%sS8إ1p=|1?= |^O*. _+ov{|,ѳzeeC[v'#Y'Wõ{9["r|++__'?ѻu~ |"߫׬ӓ~y+W??rqx&W/;ȳ|\dOo7>rO.Gޙ:OŽzWʡ[Y_[~~-a_Wg #:‡軟 tr:zÕOZw 9K7^q|_B<)AѳE/Mr~ݔߌvͯ}gƇӥ_xO̻} ;|$Jo̘'|ٺ :{C<+wso ?c] c_ⅼL,~DK Eѳ$ЏY=*nn>A; ^geߵr }o'9Py)2?3+. 6oǼ^\ |2vuߓ]A4O>>\;(pv/xg?{\~g< v{5~{\f&^;]17oӮu` _FXǭϡWᅵ[Xc`syuW>n&Gj7߳oC2 %,_ X5L{_wrx>;!"q ̃vg~Hd[c{td$W?~}=C^?M}^a\GIE'q/ԯ8oGߴGOgsf~7o^fXƺ7}ɕyGvpFμY@Kf =yߤ穽ޯ/^w7qgD2|e^O?p}#{շS]Ş{os'עߴ."%tY7w*?ˋc^à7]8W7Wvg~}v-3/Ů_[|>9y{l[yOt|"ave^?d>u7;W??vO3Y/[r ;]t/M>ŏuUȇY#9Yg[Ǯ^]}~JkӔ_ݿwFS_Gܤwt o ÿ fgta/_M n_}/WuàG=z kv>Gǭ0OuniγOKgqX~_ UOg7қc=A'_::gwJFzP/qE!e7w>zi''ZO|?m2gwNlu@;g4e|Ч+#Yo~iq}k ~n<}מ]댜eoz9*A6cy~T/B<}_&؏C?˯NNkvuD>Dҧ;'/ǴOXJqBa˺vnż˚ƛo>q?"ٌC:媷kaW4.%탇ݸ!/ї_~ HOz }=}v"z1n>/[x <o+~BG|  ѷ8Y+Q|q+o̸x3qwОf?g|z1βG&3^>NA?loyc_X>}@+9yg]G_<181y^Muez_-ܼ}_ԏx<.SqC wy9?|3GOlBG/u}ݿ!|8أYo&ߝ0/r2_ ?'/zouulv?B?'e^ ?Ok^Iԫqk]hփ}[uc=| ^:^Hp|B\ }X~KoWz?|B}&F#p3Zz!sd'y4(o?jR޺O%^u8<.uz+7ɱW8yM?F?[t1#>-K|ε<z2C/z>Q]t|6Nʸ~nW~9}~sWrZ|WȤuG ӳkz6|۹ G c^syx̻{?pЃwۮ2/c_pYg2~;: >7 ymvŌ x^et_>gʉ'c+kݯO3ݰsf>\-}eghYOog~:MigxŴޓE؟soew_W Cqf7O}~-]tt)߭|9jso<֨/c:M U}<?~3ϯ ~3_# _-ߴg= 77/v;~2'kp '|vxcqͫw<2?79~q~zG_!u[uNM~g-=?g5 7~5=‡98~̼>ťXgo?:&o<gn ϗo1(}|';|B*q/9&k0z6SK~C/,zEK/d;J9ñIj/8wyWr>0>+oyoV/Cfuqλxc ;Ҏyp~y~ǰ^?AAO=93tl~Ыx Lzu ?nn|ґq#^ߠ;q RǗ |h jO2.vR?xCzL㳿%1_}OYO}Sw|X+`_y]?|C+n_ ?A|j}7CEz <ПW'xϠKsDuu`I5FDޝfXl?Ygy죒~e=Q>3qyX?7}}rչZvq\eaƋξov;G,q3wڿxUaЭѫvųw`v^;9xa~ɣg=qEFगeexg/}xyͺybpQNov:lTys;I}:5O~M>_#:'7|5oUʓ#_ sHEr_ _Yw|@%?})߅>9uɎGħм)o'YWw->/??/D_cGs@#]N_7L'N_Njklc'5CNMh>աn;%z4=%?q|e"}ʟ%ޟ?RJ|s7xcr;^Rvd޻y"'/mxs z㊳_&}]~D:?[7r9}Y; YW/#_O/دl>yOɳi3SyC/v}%n~wP?w57Ҿj> yXr-X5~+7ᇅWFNәg.?0=?Cc9k/5>'Boo/OLNXͻlAuu_Ӹ?9oIn>7/?}y=߅Էb|_^%f|m7OM_ CB)Gu|%㒟;~/B?hst_ɼ N:hۏ;zOy5M&<['s\9Ms*N_DqN?io7/ +ocG'_aw7}ֹv|3 Ao /#Oؼ]>:t2kmM_FY1.'"ߛ/'ASObO~9i~aYiTOR_>bҞw~s7&{#'wo&x{5]GŦ?îooث][֕#v,^A|~¢SWv7d޿h=տgo ϲ>1ܷg]t 旰g(pn3"_gbEu{oԁ??m?ub}m~s*[kk}B?'Vs2G1o|- uD?eqO~`  Qy~Q86{AD7~y-鰫IvG~rP|6h!K+=;3" /N.ٿ'W.{7{*^4K{ξ;qV?37~oڍ'5OQַ+A~Js42lgo˟< zɟ!s[?ݳe|=O^rR;}\tsi߸Џ(O0Jf}z40?eYGT;ϼ{zyU-wzq)O<>xY= cfr@{~' JNN6ygԺC~7027`flf|z/ѼNu?wc!3xl|Ig~׃c=5q_y/s*:wi]qW7E\xu[n_d4&l/u#7G/N{o)]|Ah?v777Oz=\$gQa>z?LwߍwRO#jv~os4^l Fr<3?BGN{ijw͗/}~f}ޫ`|~Q>)vVR}gGAi~:cf]֩}vtݼk_ y?|wߎc_yg~; >}o^|G'շv嚯)|giz_wz;ؾ&Fn[c _B~O ]<9 } h' ~8ty Yq8;齩+\{})kOyvޠ7'GkUIo?|??9=]]W}?y&=c݊ץ^5~<Ɵ3~2r\g|w1?9|G?++l>_ZKKs:{.ܞ]?'<=|Wz|/t?#XxOi/ώql޳ʡi||th֍q8KQ|ov~G's_W"W9Z?kA?fsOf\=/%&%Ofdk~\;T3=qS">v*ݽ~~gUx웛gíȫ}b[Y{xb'dު{-8^BAii/B'ﴃz//|z`אo<xn^{p7Eڷkeuw g__V{`?=a><9| w ҏ#s˺wo)7{>80z+k˟d?jG/|h+ =7?nU\3}799^̸*Zd?TzOX_gqxPSc_y8߂><&[^e~)xƏkWYWΣ;hRhi뽪18(G\ o7"}i{z?o>v'k_-lϤǹ~l:{`3 yw5:L_O{| Ddrŗ/>㴏şߵn Q>+>':{`١2HOwVGwv]O8{'^ͼ󗘿m=K^gԧwygm=˽?jO2.w୾~ޓj}x$/NƧ3|\AKcWˁpo繷+gΫ {.oʣ~YűN{>$\_U|23]DN>}^]ϴ_}۾;9wob=yϾ/~}ȓG;xg_,YfRu߄Oa/?3?zx޴G⟪^rt_#ϔo'ݟS{ާ7s*1y_v{"yc^|ϲ/~2e< |gA3Ƌ<эy&+Qk6Wӷ+`;ׂѕ}#pgotc~{WoG<|9x _&G6*c=<_ n~wkݼi%x轾$>nޠ+~#.*oWz5߭}@Gq?y>>'xw_|*_o'Ίq _3<9iyڬ/_Y{BwG5nA_~Yg_ԼM}3~N;{+=~%G*"]}xp=I~ApEڥ_@B[/{I^LOO@7I?c': oF=~Vz3}}] l|wrm!]_\_7%w~2O^[ͼS)gp1tm]Iz8#{8k>|gv=+O o?wEv>`מu߬kzq섃=/ON?a_/֏7x]^zn(%]=}s|[|O?K@o^zb7O!s6}څqǪn~vw|8~sMrR|F6^wYlzn ?m_~X>_dO C?)C/?|~g_RyR1y3יǧ?/\<: Oī5o!wz/x Q^r?__yz_=\yO?͗]|N ~v|;.O=G#zL{_y^=%{FAwxWtO|ϓܢg??z|</  <S_~.7͐Ã/ԿzŇ|ǿ{]þ09-2yL^K2.5S˺/zn~Ȟ'MqЃ9J?米F=~[߯[+zzLyr|Owo=_5:zԧ5O0ua}5 nI>87{~'9ʔcg G3zq Dع}=ռ7>ϞFyڟikv~ ~ֿ.+vu?LϚ#!xM2n8/1R>h9}~yCvzI^1Ġ#3w-Aq9siϏ|߰ϟn^</3Ͻ_%x'Mh7n|;Y/ͯ?3f%ޣ6Bz?'z${;JrMN|Ϙ+CҮyoOōgؕۯExo^/!sON = >W$3}y>4r1pM}?=n;W#zG@᏿#:;i<Od|C7p-~i ߳W=g ·ѧg~#<艽o`}ًZq=K?'-Gě+_Nl)siOU*yoOq>3FQه3.-X+|A_s^yRçxthw[gžh+^|oi/~޸\O~~7=t)>Oo:h~qil=ӏizw_&f/ʋv%'9';M`k`}ޮ9;G,p>in>{~#r~g#nDyz5yM_bW;_`]ң/=VӼo͑ߍ_;魯|w%7ODwƿ;()q3z#E߽w<{o{A硝;?'_fw9{?8G{\.||ނ_ƁC_MD-~>5vt$g˽Ao"1 !y; ɴ+.9 z;ϑ6fЗW?O?aY8הv#K96dڡ7O]ѽ<1iu޻;=` fK+ ֓{o1s2r(y7]!|_% >L~o|X߶>S>7Aq>yBg][缿2N'Cd7fƬtj 4d=tߴ>82vtshLy1[\?{]⁓"kgH}j?¯w2J !4o\mKķn/~/_>A'm}k>oOK j,LJGhR/w#.[G޿/+ :p<ޅr2擾 /l~w~~b_۔; 9ò3_W>Bϡ?>JNGUo?_睇?ޟwv<'z7}i s?:_׸ώ_~#cWGBA^g\ҳO]{M𼇤/`9rڵW/~|YϹ{Qꉓukç3t\=I?og|7-#pзռ~{>uK^LK#i?/|?j!/A8z\Фq3p.̓gdK=D\WϫgRnԛg~[iza}Oo?A7 x.6.yO8/=noiޑtބr~ZKdw7Nçh]G?`}ȩ,/O?ryQֻ8Z''n/ =)^!y^);..uW?^y~, M s<+3:FA3nzby5_iG}~J0r }_e{Zz Jy~u~An\|K4otܾ3oi}{$xş7ѩ~d~{^-sAYO{PGƧ ~p9{wrJy?~ʼU|GWs+z @mNy9A _<[F5Ϡ+=oqg۞dzO8?^Yg3/K:?;=<'rzOXG+֣~?+.?ϧs{|Q^>E|2|_?Ad7>6M;z0|)/>i!p'J}{sn>o;o_ ūWweodjܳS߀^OF3{R 9 ROnj>MM{2;ϼ|87:u~nOK;[KٍNϛ;RN ?Xn?!\w8iۼC_!ҿ<3n_^D_wWp}l)ZƇ2>0>^vonX^ֳy◲?7zo>Wt8cDu^"!)EM:v47t(R@ DH= 9~>G ^˘6Y_U'ee̕yzsc#DupkOG)>ɇ_KOo>^ztuGoR<ҼQ077?Px?|ϕO*%gzp_Yɋu׿]O|ɷV>OsOz~^T|5%\|m(~}>h__\w=/}]_U|h~@˪>+y\wC.h?[*5~k4./ͨn{뎟:f{ݿ ||WG~Քoj'z<*zCzrKtܩP{Cy(H剪"ywrq*?o]]>Aߝ.Oh;^iMgw*_y|>C|OVh^RU:C?i_%N*}{+?~ʿ~ϓ ^GWW;|ר?~z^_x}^ͫiK;s<^1GqC~}W|8kTqwR=߬|zCZ+~~yCGFT>4o﫟*ϯpOϯv'q3_ch\S-W{oϭzVzu+睮_G~~yw{'|_7WߩtyUrzb\uP8Z]ꝗA+wxtywY-qזw?WSwz*V Gx<麌')s@yӼ5N4[x5?~_sx߫l>Y=uS>5>{r"?y'wy.};'z+(?<ʧ\/캕5^|U9S8bϫ|S9^-*_w}^j筋/㑮c~僷/^<Gy*]={KʧsG!ˮ;WCTɻ2JWcnuuOg{Wt9zgΏ>w #o'܈o_?yv¸ut}:W~Z>u2n^b=_v_U/^wv^゙{ GMïy+Onh.)j,*^k=v>cO+ʿxwT=O7OGq{zM-^?~qxgxwzwOˇ?פv}|^\K/^e;xiAS [e~E'xū˭~Tzv92>wzݿo[_͉SoN;8煅}ﯞ9VUy%O/W}sO]ߝ?}_W(>=|QT9k߼zj_#q74.W,~'>.QZyGk[,+=j>ORuX?}~ޣSr⇮Gҫs|:ʁ{!~}>>`ϧ뽥_CZ߯],ݗ~^D~Rx7>8͸z^||_7*nOu_?sa/}i[~jE|.>xnﯞ.ozg@ëRj|kY`13O}՟2V:ݏy3ꏷ>~ Gx{;%u}mg ~y_X~n'}Nk&w<}7uY+?yQ^Pqu/ѫx~^U59?Ϟ}ϽQz=s_tq`gϿu]]<=?u}3o~r_zK.qljzίi?\tRvq5xx}^[g8:}>lK~]V[9ynwzNoo81GP·7b=??jOzouU>_r'_ܟ7?⚯_e[㩯R#yb!ݿqT=m~'~X>->|G皧r%{^;vx~Y{^\y񌻼e}׿C[?KTUR9z;R}~L9e?~e>W?>_O{Ƴ GuKCK˷eǍ^>X։ܨQ\޺>_G޿}F>W]n}{Kj?U_Q8zΥR:(=_]O9ă;<>Բֱ~/}%y|^F8|1^)Ү?uXABu|Z7oXvt_ͻ-wZ|}.w|jסr.'BuJW?i[/17Ny˿^ve>\>(v齥{VK:,{}gK_u)}s}xQ/T9e/_?Ow? ǮcS|տ#^kxmׯt-ܲ[_W>I^O,Yg_웩p<᪜[ʲ+ݔO(N__m8ߧ^_r)J']ʹ3˾r*;oK^|u+]_7~^|U?پ-}v9|R:~cu|5_^y?~]Y}=ߏyw췤x+}.g~{}}n,oݯ7z:_=uJ+Ϸ7tOϓ[><˳'?C[X=Qso֩>,}ZxVc3˷>/ߟz;J⵬W>R|*:+>}f%e]-|ޝoz^?slsm@f/X-qP>>j}gw/ċ>gu(]>ϻzTy|/ث~_k>/I~u[}'*yFW?|>o79߾_s9s/vTYIe%_֧[x7uz}X9u.}l&]}W\n>^[˃myit_՗eMR_?Ƿqtqe]qhKǥ?z:7ޟÚ/}d^[;^Ϳ'8Xz/x|XKW>s}-|tz:Tܗze_&ʍ?ǟUzje_=WϽ u{_||[=Ny+9hJ^<|e~Wsc^+xw8,qps__~{_ntkK'KǞTT/m~#xǞOX瞉U˪̣}ݮnGJO )%姕gi|BwxT>k<Wwdz:\P{}'Q:)X:G9~r]Gc ^gp\t[}5߫s}:?y:ϧ>Rz*eަ9-~}^T.۫#ڗ?qOU^~||v c_g}}ko~-~,>N2Oo\_nX~χvGOR?F{?z(yɞ>6t?ʸuW3^9_27_yݯ_'q=)=ţ,ԽG;=>*W ߟܹL{]{m7VNןw}>Zhһ꡵Vn~ˣ~\kk)OƗޟyN]^UV/]w.]~o^V=t]O<N7_tp(_);~v>]e棥S^yо/xe[K__w7z%o]zʙWp+oNz~Y|~'ןϣW~S>u9_RV=y~6g~{1sخg7{?d \I_۟[W;^_O/^n-~*T|[8^W |J?\˽evK7|m J_ʏ{qgO\X: wVr]uvx*/+/?1nv:ޯYxt^_dcy]gv}ʯWzqusj}n74/u*JZ9Il=vdןןӗ~W=Py07Džz}ܨ%㜏U>su;g//j~~)?oǗ|o~.󟊗]2cu{|3js\k羃?ޢ}d<ρ|}J[g)\G]>W9',o|-8qS]·|~5.v/y;^ʓso'|!2N8tqǛV|=kxQ^>t>o׭.V:qpT*'7_7Ǐ<\7}_ヾZCEfʽD-;cWvV;ǹ_xzw^[?V|{[ʻ~Ǐ-]{Posv{d=);~i+>s׼/?t~ӝߪ?G,\PxõQ:~ǩ~/T}kFHҮ/;?P~~U(_s|O?,]o<_o^T?~?Gg>W9q[˯>UV^{J7e?ݿuzvz˾aJG+O?YZ}^NA/勾o}Wie帧#Ke^Qm19Ǐ<AfoV:UNW珕ߴ}\=5y&wځ*N7ONjz>T=˖O}^+oYp:rx{J_V}}fU}ׅ(s ϟ8WqO6^cVVo{>>9w3_/6~:.?JsW]^@!|ߍeVS8܉y8;ש8±x\*߷9߫~W>/G+,[oqXsΊˊ}\}ٿNx*W=e#K硕+W|Y]ՇO-|>o/n<;>+ݞ[q#}O[x>.GƏ7v<;}m~Yzg{~w;csO~oϳfrE_WU}˛Ѷ8DϳXz&ߟ*?>gY|_^OO(?8jq|K_Ky=3^.{]~3\Q(~ evtp{Jq]Nߧ;~VoV{~͇or}Ϸ5/Oz7_u<}?xrn>?>/_+߾}uEqx5~?#~Gߧqm^e|ZpoV}{?ۻ? V|׳83?:ߧY߯,V?/ }'<=?}?4/}y`hYhןeqHɛqfT^uO]?ߩޯ^/}|Gzpz\}͋\N}]R?x{.})tYxϻ}_dz~CsO}s:޷9[`x㝎^}œ?玹{}z}˽|GMy9ʾF{㓏#}]w(?UϽ_<'ʓ?_OpuJG+>/7.㿖_X>*:kNWquxzv鶌{i߷}=U?ƸYI*=3ޯqoXK>9}{>AvnOt^p{g +~V8e^_}xiT< 離\t9K=}H}->o+J'O`oU/o]^UNʏϿ-sr=?f~E~~)iig^ǫ˽wG oy7ᵯWC3S}[~y}]Fnt?Tz{/-]Ogu~Wg>?:s{{2jy?oT\RzZx>G1~E>~\Ox^Y>Jw;GʥO]֓),<Gߏ?I{-}y<>/G{{uLq2j墟ۡ:y.,Z/>^螏7wr~z~V_|/nt/˟r㷽uٯ#?4uV}}>_oӽ<׸`ozݐvۿC s_|_<J N1ߧԞcOK;k>Qw=iW1^qڷ}V[{->_(^O7ϙ},?Z}qyGVz V/:Z{.¸)>AvW{>㜚^,.x{׼)X5v̟㮽9~L/QGi_ǥ[w}NzuE=eGxQ~ѯ֍/Y}\~|>}zJ|Gv}}l~IJ߃kYZ/G?qܟ~ϻydˣϭg)hw>OeÊJGS<#<_A]tgYa='ΫWe\g3,~_pkz9?u{j轕W||] -{˻9Py^ϔgk._>ߵTZ~Y}㜗eݣq%}3[z9S|}-/M-\[i\պP#eg}=~?:,(ejyri ^~ݟGV=v~!-Ps |_y|O㇇ގyz/C}?К>o~R~mW:T\5~Ω]U9?^6x[ʵWP9= ןcW{[˼nߺ;}*߿@^s|oӿꫯBOK{o囗,?~#˟e_RqʷR-ߝW*:C?YӟS:wƲ~˫(}}?1ܻ_~}}ϟr/ϱߟeg]W~WbC/r(^_V޿z8,<wZp/s.ݳ]ó~ȧeYX{}Xz.;w 3^}e|WuCzU*},^=_By齷\X9//߶B==|Nu:|KOs'}=W]f_\ֳY|>(ݭ8w]ߟ޿~/Z >_qp7_?j٫,?|'q]_oM{*_ߏ'}6_/<~-랕JoU~[:=esٗU_яµpU=`e;\o/<>x~fxٗԾƇ幑?o<:f}~rfj{V/||cw|}yz}-;=?gi><ݾ_$>6|?xz7f짢x[~˲ʅ?XtJw_v캗c)|sV<ګ}w|^ɲ.qX~Az>e<ʱ;9/_SC>oz~/ʯߧ-륕#vޞxSpji?gɮ]Wܯ~_pzYkpգSKﭼf87?^;_^.ڟt~Qܟ_qן+jx/s=~_|۞U}_`>[6->[CI^+MK*kZv{p ʍ-׽|e7R뾿|1ݓq7Kh,]}}+ПwGj4,^>GqN+{K'ǯYz:oKx-ϯ?9N}ϟg׳}|X|I+>~SP?rk̳YGq/s!;y&;} co7䜶zޛ:,eeo ^ɗ}s֮Uţ/Ѷg4_zx:ʏT}?w?@:YƷTܟ`C|<? zyLy:YX3^b}aXχ>\gcGC~6/S=m;9B_8?}<9w8?/ωtҡs8|~n±p}|,uxje^Izwtv?ŽfoOt>ޤx~q-뭭|-W.|Oͫra|z$ݎZyy=re_Wa7ίo wjg|xO~7t}},_z\ǹgy^sMKyW>&oNϯ疎>þ{V93|?O>??~}>x}>x}>x}>x}>x}>x}>x}֎>x}>x}>x}>x}>x}>x}>x}>x}>x}>x}>x}>;?ڿ;~ww~?_o߿Ư?ǿOq?OO~ɟ۟͟?wwWQo~_gO/?|{O?_?_?O/rgſl{c$~|?Jlc8u;/GW_muaDFtaDFtaDFvadFvadFvaTQFuaTQFuaTu[u[u[u[u[w{w{w{w{w{qtGqtGqtGqtGqtGqvgqvgqvgqvgqvgquWquWquWquWquǗ_Ο3Ϝ?k},ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa>,ه%dÒ}XKa1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒcXr Ka1,9%ǰÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa9,9%ÒsXrKa5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װ\ÒkXr Ka5,%װj|e?w߅7>>>>> 7n @p 7n"Dp&M7n!Bp -[n!Bp7! nwCpw#wG;pw{ @=p{ D'=pO{"D½p/{! ^BzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW^=xzW* * * * * * * * * * * * * * * * * * * * * * * * * *J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J*J * * * * * * * * * * * * * * * * * * * * * * * * *j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6j6jvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvjvNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN.................................................~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o=~{o='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO ='ߞ~{oO =^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/^ ~{o/6i8]E @訲7rh~)F[8?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷?|o÷~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?|~÷o?||{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{|{^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ^|{ŷ>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷>|÷O~v??,hexbin/R/0000755000175100001440000000000012546727117011762 5ustar hornikusershexbin/R/hexbin.s4.R0000644000175100001440000002701011551510077013675 0ustar hornikusers## namespace *internal* function: addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds) hexbin <- function(x, y = NULL, xbins = 30, shape = 1, xbnds = range(x), ybnds = range(y), xlab = NULL, ylab = NULL, IDs = FALSE) { call <- match.call() ## (x,y, xlab, ylab) dealing xl <- if (!missing(x)) deparse(substitute(x)) yl <- if (!missing(y)) deparse(substitute(y)) xy <- xy.coords(x, y, xl, yl) ch0 <- function(u) if(is.null(u)) "" else u xlab <- if (is.null(xlab)) ch0(xy$xlab) else xlab ylab <- if (is.null(ylab)) ch0(xy$ylab) else ylab if(! (is.character(xlab) || is.expression(xlab))) stop("xlab must be a character or expression") if(! (is.character(ylab) || is.expression(ylab))) stop("ylab must be a character or expression") x <- xy$x y <- xy$y n <- length(x) na <- is.na(x) | is.na(y) has.na <- any(na) if (has.na) { ok <- !na x <- x[ok] y <- y[ok] n0 <- n na.pos <- which(na) n <- length(x) } if(diff(xbnds) <= 0) stop("xbnds[1] < xbnds[2] is not fulfilled") if(!missing(xbnds) && any(sign(xbnds - range(x)) == c(1,-1))) stop("'xbnds' must encompass range(x)") if(diff(ybnds) <= 0) stop("ybnds[1] < ybnds[2] is not fulfilled") if(!missing(ybnds) && any(sign(ybnds - range(y)) == c(1,-1))) stop("'ybnds' must encompass range(y)") jmax <- floor(xbins + 1.5001) #imax <- 2 * floor((xbins * shape)/sqrt(3) + 1.5001) c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) imax <- trunc((jmax*c1 -1)/jmax + 1) lmax <- jmax * imax ans <- .Fortran("hbin", x = as.double(x), y = as.double(y), cell = integer(lmax), cnt = integer(lmax), xcm = double(lmax), ycm = double(lmax), xbins = as.double(xbins), shape = as.double(shape), xbnds = as.double(xbnds), ybnds = as.double(ybnds), dim = as.integer(c(imax, jmax)), n = as.integer(n), cID = if(IDs) integer(n) else as.integer(-1), PACKAGE = "hexbin")[-(1:2)] ## cut off extraneous stuff if(!IDs) ans$cID <- NULL if(IDs && has.na) { ok <- as.integer(ok) ok[!na] <- ans$cID ok[na] <- NA ans$cID <- ok } nc <- ans$n length(ans$cell) <- nc length(ans$cnt) <- nc length(ans$xcm) <- nc length(ans$ycm) <- nc if(sum(ans$cnt) != n) warning("Lost counts in binning") new("hexbin", cell = ans$cell, count = ans$cnt, xcm = ans$xcm, ycm = ans$ycm, xbins = ans$xbins, shape = ans$shape, xbnds = ans$xbnds , ybnds = ans$ybnds, dimen = c(imax, jmax), n = n, ncells = ans$n, call = call, xlab = xlab, ylab = ylab, cID = ans$cID, cAtt = integer(0)) #dimen = ans$dim }## hexbin setClassUnion("integer or NULL",# < virtual class, used in 'cID' slot members = c("integer","NULL")) ## MM: I've learned that we should think twice before defining such ## "or NULL" classes: ## setClassUnion("vector or NULL",# < virtual class, used in 'cAtt' slot ## members = c("vector","NULL")) setClass("hexbin", representation(cell = "integer", count = "numeric",##count = "integer", xcm = "numeric", ycm = "numeric", xbins = "numeric", shape = "numeric", xbnds = "numeric", ybnds = "numeric", dimen = "numeric", n = "integer", ncells = "integer", call = "call", xlab = "vector", ylab = "vector", #xlab = "character", ylab = "character", cID = "integer or NULL", cAtt = "vector")## "or NULL" ) #setIs("hexbin", function(hbin) class(hbin)=="hexbin") ## FIXME: add 'validity checking method! setGeneric("hcell2xy", function(hbin, check.erosion = TRUE) standardGeneric("hcell2xy")) setMethod("hcell2xy", "hexbin", function(hbin, check.erosion = TRUE) { xbins <- hbin@xbins xbnds <- hbin@xbnds c3 <- diff(xbnds)/xbins ybnds <- hbin@ybnds c4 <- (diff(ybnds) * sqrt(3))/(2 * hbin@shape * xbins) jmax <- hbin@dimen[2] cell <- hbin@cell - 1 i <- cell %/% jmax j <- cell %% jmax y <- c4 * i + ybnds[1] x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1] if(check.erosion && inherits(hbin,"erodebin")) list(x = x[hbin@eroded], y = y[hbin@eroded]) else list(x = x, y = y) }) setGeneric("getHexDxy", function(hbin) standardGeneric("getHexDxy")) setMethod("getHexDxy", "hexbin", function(hbin){ sx <- hbin@xbins/diff(hbin@xbnds) sy <- (hbin@xbins * hbin@shape)/diff(hbin@ybnds) list(dx=.5/sx, dy=(1/sqrt(3))/(2*sy)) }) setClass("erodebin", representation("hexbin", eroded = "logical", cdfcut = "numeric", erode = "integer")) setGeneric("erode", function(hbin, cdfcut = 0.5) standardGeneric("erode")) ## currently define the 'hexbin' method (also) as standalone function: erode.hexbin <- function(hbin, cdfcut = 0.5) { if(!is(hbin,"hexbin")) stop("first argument must be a hexbin object") #bin.att <- attributes(hbin) cell <- hbin@cell cnt <- hbin@count tmp <- sort(cnt) cdf <- cumsum(tmp)/sum(cnt) good <- cdfcut <= cdf if(!any(good)) return("no cells selected") crit <- min(tmp[good]) good <- crit <= cnt cell <- cell[good] cnt <- cnt[good] #hbin@cell <- cell #hbin@count <- cnt n <- length(cell) bdim <- hbin@dimen L <- bdim[1] * bdim[2] ans <- .Fortran("herode", cell = as.integer(cell), cnt = as.integer(cnt), n = n, bdim = as.integer(bdim), erode = integer(L), ncnt = integer(L), ncell = integer(L), sides = integer(L), neib = integer(6 * L), exist = logical(L + 1), PACKAGE = "hexbin") $ erode length(ans) <- n ehbin <- new("erodebin", hbin, cdfcut = cdfcut, eroded = good, erode = ans) #hbin@erode <- ans #class(hbin) <- c(class(hbin),"erodebin") ehbin } setMethod("erode", "hexbin", erode.hexbin) setGeneric("getHMedian", function(ebin) standardGeneric("getHMedian")) setMethod("getHMedian", "erodebin", function(ebin) { xy <- hcell2xy(ebin) stopifnot(1 == length(med <- which.max(ebin@erode))) med.x <- xy$x[med] med.y <- xy$y[med] list(x = med.x, y = med.y) }) ## Still define the 'hexbin' plot method (also) as standalone function: ## This is deprecated! gplot.hexbin <- function(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n, beg = 90, end = 15), xlab = NULL, ylab = NULL, main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip="on", verbose = getOption("verbose")) { if(!is(x,"hexbin")) stop("first argument must be a hexbin object") if(minarea < 0) stop("Minimum area must be non-negative") if(maxarea > 1) warning("Maximum area should be <= 1 this leads to overlapping hexagons") if(minarea > maxarea) stop("Minarea must be <= maxarea") if (length(colorcut) > 1) { # a sequence 0,...,1 if(colorcut[1] != 0) stop("Colorcut lower boundary must be 0") if(colorcut[length(colorcut)] != 1) stop("Colorcut upper boundary must be 1") } else { colorcut <- if(colorcut > 1) seq(0, 1, length = min(c(17, colorcut, maxcnt))) else 1 } if(is.logical(legend)) { if(legend) stop("Give the legend width") else legend <- 0 } else stopifnot(is.numeric(legend) && length(legend) == 1) type <- match.arg(type) xaxt <- match.arg(xaxt) yaxt <- match.arg(yaxt) ## ----- plotting starts ------------------------ if (newpage) grid.newpage() hv.ob <- hexViewport(x, offset = unit(legend,"inches")) pushViewport(hv.ob@hexVp.off) grid.rect() if(xaxt != "n") grid.xaxis() if(yaxt != "n") grid.yaxis() ## xlab, ylab, main : if(is.null(xlab)) xlab <- x@xlab if(is.null(ylab)) ylab <- x@ylab if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90) if(nchar(main) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(type != "n") { if(clip == "on") { popViewport() pushViewport(hv.ob@hexVp.on) } grid.hexagons(x, style = style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt = maxcnt, check.erosion = FALSE, trans = trans, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp, verbose = verbose) } popViewport()# plot #popViewport()# fig ## ----- Legend ------------------------ if(legend > 0) { if(!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation") if(verbose) cat("plot.hexbin( legend > 0): ... hex.legend()\n") inner <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[1]/x@xbins ##inner <- as.numeric(convertUnit(hv.ob@plt[1],"inches"))/x@xbins ##outer <- (inner * sqrt(3))/2 ##switch(style, ## lattice = , ## centroids = { ## if(length(colorcut) * outer > ysize - 1) { ## warning("Colorcut is being shortened") ## colorcut <- seq(0, 1, ## max(1, floor((ysize - 1)/outer))) ## } ## } ## ) ysize <- getPlt(hv.ob, ret.unit = "inches", numeric = TRUE)[2] #as.numeric(convertUnit(hv.ob@plt[2],"inches")) legVp <- viewport(x = unit(1,"npc") - convertX(unit(legend,"inches"), "npc"), #y = convertY(unit(mai[1],"inches"),"npc"), y = hv.ob@mar[1], #height = unit(1,"npc") - #convertY(unit(mai[3]+mai[1],"inches"),"npc"), height = unit(1,"npc")-(hv.ob@mar[1]+ hv.ob@mar[3]), width = convertUnit(unit(legend,"inches"),"npc"), default.units = "native", just = c("left","bottom"), xscale = c(0, legend), yscale = c(0, ysize)) if(type != "n") { pushViewport(legVp) grid.hexlegend(legend, ysize = ysize, lcex = lcex, inner = inner, style = style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt = maxcnt, trans = trans, inv = inv, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) popViewport() } } invisible(list(plot.vp = hv.ob, legend.vp = if(legend) legVp)) } ## gplot.hexbin() setMethod("plot", signature(x = "hexbin", y = "missing"), gplot.hexbin) setMethod("show", "hexbin", function(object) { cat("'hexbin' object from call:", deparse(object@call), "\n") dm <- object@dimen cat("n =", object@n, " points in nc =", object@ncells, " hexagon cells in grid dimensions ", dm[1], "by", dm[2],"\n") invisible(object) }) setMethod("summary", "hexbin", function(object, ...) { show(object, ...) print(summary(data.frame(cell = object@cell, count = object@count, xcm = object@xcm, ycm = object@ycm), ...)) if(!is.null(object@cID)) { cat("IDs: "); str(object@cID) } }) if(FALSE) { ##-- todo -- #setMethod("identify" identify.hexbin <- function(x, labels = x$cnt, offset = 0, ...) { if(length(labels) != x$n) stop("labels not the same length as number of cells") ##NL: Should this be a warning? ## -> typically default method: identify(hcell2xy(x), labels = labels, offset = offset, ...) } }#not yet hexbin/R/smoothHexbin.R0000644000175100001440000000260111551510077014541 0ustar hornikuserssetClass("smoothbin", representation("hexbin", wts="numeric")) setGeneric("hsmooth", function(bin, wts) standardGeneric("hsmooth")) smooth.hexbin <- function(bin, wts = c(48, 4, 1)) { if(!is(bin,"hexbin")) stop("first argument must be a hexbin object") cell <- bin@cell - 1 n <- as.integer(length(cell)) cnt <- bin@count xbins <- bin@xbins bdim <- bin@dimen row <- bdim[1] col <- bdim[2] ncol <- col + 4 nrow <- row + 4 nmax <- ncol * nrow sm <- rep.int(0:0, nmax) nr <- cell %/% col + 2 nc <- cell %% col + 3 pad <- rep.int(0:0, nmax - n) cell <- c(nr * ncol + nc, pad) cnt <- c(cnt, pad) ans <- .Fortran("hsm", cell = as.integer(cell), cnt = as.integer(cnt), n = n, nmax = as.integer(nmax), sm = as.integer(sm), ncol = as.integer(ncol), wts = as.integer(wts), PACKAGE = "hexbin")[c("cell","cnt","n")] n <- ans$n length(ans$cell) <- length(ans$cnt) <- n bin@xbins <- xbins + 4 bin@xbnds <- addBit(bin@xbnds, f = 2/xbins) bin@ybnds <- addBit(bin@ybnds, f = 2/xbins) bin@dimen <- c(nrow, ncol) bin@cell <- ans$cell bin@count <- ans$cnt new("smoothbin", bin, wts=wts) } setMethod("hsmooth", "hexbin", smooth.hexbin) hexbin/R/hexutil.R0000644000175100001440000000721211551510077013557 0ustar hornikusershcell2xyInt <- function(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL) { if(missing(hbin) && (is.null(xbnds) || is.null(ybnds))) stop("Need a hexbin object or boundaries to make lattice") if(missing(hbin) && (is.null(xbins) || is.null(shape))) stop("Need xbins and shape to make a lattice") if(!missing(hbin)) { xbins <- hbin@xbins shape <- hbin@shape xbnds <- if(is.null(xbnds)) hbin@xbnds else xbnds ybnds <- if(is.null(ybnds)) hbin@ybnds else ybnds dimen <- hbin@dimen } if(missing(hbin)) { jmax <- floor(xbins + 1.5001) imax <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) dimen <- c(imax, jmax) } cell <- 1:(dimen[1]*dimen[2])-1 i <- cell %/% dimen[2] j <- cell %% dimen[2] list(i=i+1, j=j+1) } hgridcent <- function(xbins, xbnds, ybnds, shape, edge.add=0) { ## auxiliary for hexGraphPaper(): jmax <- floor(xbins + 1.5001) c1 <- 2 * floor((xbins *shape)/sqrt(3) + 1.5001) imax <- (jmax*c1 -1)/jmax + 1 dimen <- c(imax, jmax) c3 <- diff(xbnds)/xbins c4 <- (diff(ybnds) * sqrt(3))/(2 * shape * xbins) if(edge.add > 0) { xbnds <- xbnds + 1.5*c(-edge.add*c3, edge.add*c3) ybnds <- ybnds + c(-edge.add*c4, edge.add*c4) dimen <- dimen + rep.int(2*edge.add, 2) } jmax <- dimen[2] cell <- 1:(dimen[1]*dimen[2]) i <- cell %/% jmax j <- cell %% jmax y <- c4 * i + ybnds[1] x <- c3 * ifelse(i %% 2 == 0, j, j + 0.5) + xbnds[1] list(x = x, y = y, dimen = dimen, dx=c3, dy=c4) } hexGraphPaper <- function(hb, xbnds=NULL, ybnds=NULL, xbins=30, shape=1, add=TRUE, fill.edges=1, fill=0, border=1) { if(missing(hb) && (is.null(xbnds) || is.null(ybnds))) stop("Need a hexbin object or boundaries to make lattice") if(!missing(hb)) { xbins <- hb@xbins shape <- hb@shape xbnds <- if(is.null(xbnds)) hb@xbnds else xbnds ybnds <- if(is.null(ybnds)) hb@ybnds else ybnds dimen <- hb@dimen } xy <- hgridcent(xbins, xbnds, ybnds, shape, edge.add=fill.edges) if(add){ sx <- xbins/diff(xbnds) sy <- (xbins * shape)/diff(ybnds) inner <- 0.5 outer <- (2 * inner)/sqrt(3) dx <- inner/sx dy <- outer/(2 * sy) if(add){ hexC <- hexcoords(dx, dy, sep=NULL) hexpolygon (xy$x, xy$y, hexC, dx, dy, fill = fill, border = border, hUnit = "native") } } invisible(xy) } hexTapply <- function(hbin,dat,FUN=sum,...,simplify=TRUE) { if(is.null(hbin@cID)) stop("Must have cell ID's to do this operation \n please re-bin data using IDs = TRUE") if((length(dat)> 0) && (length(dat) != length(hbin@cID))) stop("Length of IDs does not match the length of the data") tapply(dat,hbin@cID,FUN,...,simplify=simplify) } optShape <- function(vp, height=NULL, width=NULL, mar=NULL) { if(missing(vp) && (is.null(height) || is.null(width))) stop("Need a viewport object or height and width of the plotting region.") if(!missing(vp)) { if("hexVP" %in% class(vp)) { height <- vp@plt[2] width <- vp@plt[1] } else if("viewport"%in%class(vp)) { #height <- convertHeight(unit(1,"npc"),"inches") #width <- convertWidth (unit(1,"npc"),"inches") height <- convertUnit(vp$height,"inches") width <- convertUnit(vp$width,"inches") } else stop("need valid viewport or hexViewport") } if(!is.null(mar)){ height <- height - mar[1] - mar[3] width <- width - mar[2] - mar[4] } shape <- as.numeric(height)/as.numeric(width) shape } inout.hex <- function(hbin,mincnt) { if(is.null(hbin@cID)) stop("bin object must have a cID slot, \n try re-binning with ID = TRUE") tI <- table(hbin@cID) which(hbin@cID%in%(names(tI)[tI ### Copyright (C) 2001-2005 Saikat DebRoy ### ### This file is part of the lattice package for R. ### It is made available under the terms of the GNU General Public ### License, version 2, or at your option, any later version, ### incorporated herein by reference. ### ### This program is distributed in the hope that it will be ### useful, but WITHOUT ANY WARRANTY; without even the implied ### warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ### PURPOSE. See the GNU General Public License for more ### details. ### ### You should have received a copy of the GNU General Public ### License along with this program; if not, write to the Free ### Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, ### MA 02110-1301, USA construct.legend <- function(legend = NULL, key = NULL, fun = "draw.key") { if (is.null(legend) && is.null(key)) return(NULL) if (is.null(legend)) legend <- list() if (!is.null(key)) { space <- key$space x <- y <- corner <- NULL if (is.null(space)) { if (any(c("x", "y", "corner") %in% names(key))) { stopifnot(is.null(x) || (length(x) == 1 && x >= 0 && x <= 1)) stopifnot(is.null(y) || (length(y) == 1 && y >= 0 && y <= 1)) stopifnot(is.null(corner) || (length(corner) == 2 && all(corner %in% c(0, 1)))) space <- "inside" x <- key$x y <- key$y corner <- key$corner ## check for valid values } else space <- "top" } if (space != "inside" && space %in% names(legend)) stop(gettextf("component '%s' duplicated in key and legend", space)) key.legend <- list(fun = fun, args = list(key = key, draw = FALSE)) key.legend$x <- x key.legend$y <- y key.legend$corner <- corner legend <- c(list(key.legend), legend) names(legend)[1] <- space } legend } extend.limits <- function(lim, length = 1, axs = "r", prop = if (axs == "i") 0 else lattice.getOption("axis.padding")$numeric) { ## if (!is.numeric(lim)) NA if (all(is.na(lim))) NA_real_ # or lim? else if (is.character(lim) ) { c(1, length(lim)) + c(-1, 1) * if (axs == "i") 0.5 else lattice.getOption("axis.padding")$factor } else if (length(lim) == 2) { if (lim[1] > lim[2]) { ccall <- match.call() ccall$lim <- rev(lim) ans <- eval.parent(ccall) return (rev(ans)) } if (!missing(length) && !missing(prop)) stop("'length' and 'prop' cannot both be specified") if (length <= 0) stop("'length' must be positive") if (!missing(length)) { prop <- (as.numeric(length) - as.numeric(diff(lim))) / (2 * as.numeric(diff(lim))) } if (lim[1]==lim[2]) lim + 0.5 * c(-length,length) else { d <- diff(as.numeric(lim)) lim + prop * d * c(-1,1) } } else { print(lim) stop("improper length of 'lim'") } } limitsFromLimitlist <- function(have.lim, lim, relation, limitlist, used.at, numlimitlist, axs, npackets) ## have.lim: logical, whether xlim/ylim was explicitly specified ## lim: the specified limit if have.lim = TRUE ## relation: same/free/sliced ## limitlist: list of limits from prepanel calculations, one for each panel ## numlimitlist: (optional) numeric locations for factors (lim ## will be levels including unused ones) ## axs: "r", "i" etc, passed on to extend.limits ## return value depends on relation. (See limits.and.aspect below, ## where this is used, for partial enlightenment.) { if (relation == "same") { ## The problem here is that we need to figure out the overall ## limit required from the limits of each panel. This could be ## a problem for two reasons. First, some panels could have no ## data in them, in which case the corresponding limits would ## be NA. Secondly, the limits could be either numeric or ## character vectors (the latter for factors). When relation = ## same, the type should be same across panels. When numeric, ## we just take range, leaving out NAs. But what about ## factors? Is it OK to assume that all the non-NA vectors ## would be exactly the same ? They should be, since levels(x) ## would not change even if not all levels are ## represented. So, I'm just taking unique of all the vectors ## concatenated, excluding NA's ## Additional complication: Need to preserve class of limits, ## to be used later in tick location/label calculation. Not a ## problem in other cases, but here unlist-ing loses the ## class. #if (!have.lim) ## always calculate the limits from prepanel first: ## should check that all classes are the same. How ? What ## about NA's ? Arrgh! ## to handle NA's, how about: all.na <- unlist(lapply(limitlist, function(x) all(is.na(x)))) class.lim <- ## retain non-NA limitlists only lapply(limitlist[!all.na], class) ## class.lim is a list now, may be length 0 limits <- unlist(limitlist) ## loses the class attribute ## if (length(limits) > 0) if (sum(!is.na(limits)) > 0) { if (is.character(limits)) { limits <- unique(limits[!is.na(limits)]) slicelen <- diff(extend.limits(limits, axs = axs)) } else ## if (is.numeric(limits)) # or dates etc { limits <- extend.limits(range(as.numeric(limits), finite = TRUE), axs = axs) slicelen <- diff(range(limits, finite = TRUE)) } ## hopefully put back appropriate class of limits: ## FIXME: date changes may have messed this up if (length(class.lim) > 0) class(limits) <- if (all(class.lim[[1]] == "integer")) "numeric" else class.lim[[1]] ## (have to handle "integer" specially, since variable ## specifications like 1:10 are rather common, and ## class() <- "integer" would turn the limits into ## integers) } else { limits <- c(0,1) slicelen <- 1 } if (have.lim) { if (is.list(lim)) stop("limits cannot be a list when relation = same") old.limits <- limits limits <- lim ## lim overrides prepanel except NAs if (!is.character(limits) && !is.character(old.limits)) { limits[is.na(limits)] <- old.limits[is.na(limits)] } slicelen <- ## this no longer works for dates (R 2.6) ## if (is.numeric(lim)) diff(range(lim)) ## else length(lim) + 2 if (is.character(limits)) length(limits) + 2 else diff(range(as.numeric(limits))) } ans <- list(limits = limits, slicelen = slicelen) } else if (relation == "sliced") { if (have.lim) { if (is.list(lim)) { limits <- rep(lim, length.out = npackets) } else warning("Explicitly specified limits ignored") } slicelen <- limitlist for (i in seq_along(limitlist)) { slicelen[[i]] <- ## if (is.numeric(limitlist[[i]])) if (!is.character(limitlist[[i]])) { if (any(is.finite(limitlist[[i]]))) ## range unnecessary, but... diff(range(as.numeric(limitlist[[i]]), finite = TRUE)) else NA_real_ } else if (!any(is.na(numlimitlist[[i]]))) diff(range(as.numeric(numlimitlist[[i]]))) else NA_real_ } slicelen <- (if (axs == "i") 1 else 1 + 2 * lattice.getOption("axis.padding")$numeric) * max(unlist(slicelen), na.rm = TRUE) for (i in seq_along(limitlist)) { if (is.numeric(limitlist[[i]])) limitlist[[i]] <- extend.limits(limitlist[[i]], length = slicelen) } for (i in seq_along(numlimitlist)) { if (!all(is.na(numlimitlist[[i]]))) numlimitlist[[i]] <- extend.limits(as.numeric(numlimitlist[[i]]), length = slicelen) } ans <- list(limits = limitlist, used.at = used.at, numlimitlist = numlimitlist, slicelen = slicelen) } else if (relation == "free") { if (have.lim) { ## This is the only situation where limits can be a list ## (doesn't make sense when relation="same", ignored when ## relation="sliced"). Even if limits is not a list (but ## is specified), it will be treated as a list, and ## repeated as necessary (see further comments below). if (!is.list(lim)) lim <- list(lim) ## There's a subtle consideration here. It is possible ## for some panels to have nothing in them (or only NA's). ## Such panels usually have their prepanel functions ## return NA. When 'limits' is specified as a list, this ## will be interpreted as the limit specification for the ## non-empty panels only (this is an arbitrary choice, but ## it usually makes more sense, even though it's less ## general than the other choice). ## which ones are non-NA? id <- which(sapply(limitlist, function(x) !all(is.na(x)))) ## replace these with the limits supplied, except if the ## supplied limits are NULL, in which case retain limits ## calculated by prepanel. old.limitlist <- limitlist limitlist[id] <- lim which.null <- sapply(limitlist, is.null) limitlist[which.null] <- old.limitlist[which.null] ## lim overrides prepanel except NAs for (i in seq_along(limitlist)) { if (!is.character(limitlist[[i]]) && !is.character(old.limitlist[[i]])) { isna <- is.na(limitlist[[i]]) limitlist[[i]][isna] <- old.limitlist[[i]][isna] } } } for (i in seq_along(limitlist)) { if (!all(is.na(limitlist[[i]])) && !is.character(limitlist[[i]])) limitlist[[i]] <- ## preserves class extend.limits(limitlist[[i]], axs = axs) ## o.w., keep it as it is } slicelen <- numeric(length(limitlist)) for (i in seq_along(limitlist)) slicelen[i] <- if (!is.character(limitlist[[i]])) diff(range(as.numeric(limitlist[[i]]))) else if (!any(is.na(numlimitlist[[i]]))) diff(range(numlimitlist[[i]])) else NA_real_ ans <- list(limits = limitlist, used.at = used.at, numlimitlist = numlimitlist, slicelen = slicelen) } ans } complete_names <- function(x, template, allow.invalid = FALSE) { pid <- pmatch(names(x), names(template), duplicates.ok = TRUE) if (allow.invalid) { x <- x[!is.na(pid)] pid <- pid[!is.na(pid)] } else { if (any(is.na(pid))) warning("Invalid or ambiguous component names: ", paste(names(x)[which(is.na(pid))], collapse = ", ") ) } if (any(duplicated(pid))) stop("Multiple matches to component name") names(x) <- names(template)[pid] x } getFunctionOrName <- function(FUN) ## Try lattice namespace first? Does that happen automatically? { if (is.function(FUN)) FUN else if (is.character(FUN)) get(FUN) else eval(FUN) } trellis.skeleton <- function(formula = NULL, cond, aspect = default.args$aspect, # argument in xyplot as.table = default.args$as.table, between = default.args$between, key = NULL, legend = NULL, page = default.args$page, main = default.args$main, sub = default.args$sub, par.strip.text = default.args$par.strip.text, layout = default.args$layout, skip = default.args$skip, strip = default.args$strip.default, # argument in xyplot strip.left = FALSE, xlab.default = NULL, ylab.default = NULL, xlab = NULL, # argument in xyplot ylab = NULL, # argument in xyplot xlab.top = NULL, ylab.right = NULL, panel, # argument in xyplot xscale.components = default.args$xscale.components, yscale.components = default.args$yscale.components, axis = default.args$axis, subscripts = TRUE, # ignored, for reasons given above index.cond = NULL, perm.cond = NULL, ..., par.settings = NULL, plot.args = NULL, lattice.options = NULL) { default.args <- lattice.getOption("default.args") if (is.null(skip)) skip <- FALSE foo <- list(formula = formula, as.table = as.table, aspect.fill = (aspect == "fill"), ## key = key, legend = construct.legend(legend = legend, key = key), panel = panel, page = page, layout = layout, skip = skip, strip = if (is.logical(strip) && strip) "strip.default" else strip, strip.left = if (is.logical(strip.left) && strip.left) strip.custom(horizontal = FALSE) else strip.left, xscale.components = xscale.components, yscale.components = yscale.components, axis = axis, xlab = xlab, ylab = ylab, xlab.default = xlab.default, ylab.default = ylab.default, xlab.top = xlab.top, ylab.right = ylab.right, main = main, sub = sub, x.between = 0, y.between = 0, par.settings = par.settings, plot.args = plot.args, lattice.options = lattice.options, par.strip.text = par.strip.text, index.cond = index.cond, perm.cond = perm.cond) if (!is.null(between$x)) foo$x.between <- between$x if (!is.null(between$y)) foo$y.between <- between$y foo$condlevels <- lapply(cond, levels) list(foo = foo, dots = list(...)) } cond.orders <- function(foo, ...) ## function to determine order of panels within a cond. variable ## foo: trellis object-to-be ## calculate actual values for index.cond and perm.cond. ## index.cond can be a function, in which case it would be used to ## determing order of levels within conditioning variables ## Question: should these be determined at run-time? Wouldn't be ## impossible, but has the disadvantage that looking at the ## trellis object will be totally uninformative in the default ## case (when both would be NULL). In a sense, this is fine, since ## having index.cond be a function is similar to having a prepanel ## function. After all, the results depend only on the panel ## contents, and those cannot be changed via update. { ## the following to be used for changing order of conditioning ## variables and indexing their levels. The object foo already has ## components index.cond and perm.cond as whatever was passed to ## the original function call. If these are NULL, suitable ## defaults need to be computed. If foo$index.cond is a function, ## index.cond has to be computed appropriately. index.cond <- vector(mode = "list", length = length(foo$condlevels)) for (i in seq_along(foo$condlevels)) index.cond[[i]] <- seq_along(foo$condlevels[[i]]) perm.cond <- seq_len(length(foo$condlevels)) if (!is.null(foo$perm.cond)) { if (all(sort(foo$perm.cond) == perm.cond)) perm.cond <- foo$perm.cond else stop("Invalid value of perm.cond") } if (!is.null(foo$index.cond)) { if (is.list(foo$index.cond) && length(foo$index.cond) == length(index.cond)) { for (i in seq_along(foo$condlevels)) index.cond[[i]] <- index.cond[[i]][foo$index.cond[[i]]] } else if (is.function(foo$index.cond)) { FUN <- foo$index.cond nplots <- length(foo$panel.args) panel.order <- numeric(nplots) for (count in seq_len(nplots)) { if (is.list(foo$panel.args[[count]])) { pargs <- c(foo$panel.args.common, foo$panel.args[[count]], list(...)) prenames <- names(formals(FUN)) if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)] panel.order[count] <- do.call("FUN", pargs) } else ## this happens for empty panels { is.na(panel.order) <- count # panel.order[count] <- NA } } dim(panel.order) <- sapply(foo$condlevels, length) for (i in seq_along(foo$condlevels)) index.cond[[i]] <- order(apply(panel.order, i, mean, na.rm = TRUE)) } else stop("Invalid value of index.cond") } list(index.cond = index.cond, perm.cond = perm.cond) } construct.scales <- function(draw = TRUE, axs = "r", tck = 1, tick.number = 5, at = FALSE, labels = FALSE, log = FALSE, alternating = TRUE, relation = "same", abbreviate = FALSE, minlength = 4, limits = NULL, format = NULL, equispaced.log = TRUE, lty = FALSE, lwd = FALSE, cex = FALSE, rot = FALSE, col = FALSE, col.line = col, alpha = FALSE, alpha.line = alpha, font = FALSE, fontfamily = FALSE, fontface = FALSE, lineheight = FALSE, ..., ## NOTE: ... is currently ignored x = NULL, y = NULL) { ## top-level values x.scales <- y.scales <- list(draw = draw, axs = axs, tck = tck, tick.number = tick.number, at = at, labels = labels, log = log, alternating = alternating, relation = relation, abbreviate = abbreviate, minlength = minlength, limits = limits, format = format, equispaced.log = equispaced.log, lty = lty, lwd = lwd, cex = cex, rot = rot, col = col, col.line = col.line, alpha = alpha, alpha.line = alpha.line, font = font, fontfamily = fontfamily, fontface = fontface, lineheight = lineheight) ## override by component-specific values if (!is.null(x)) { if (is.character(x)) x <- list(relation = x) x <- complete_names(x, x.scales) x.scales[names(x)] <- x } if (!is.null(y)) { if (is.character(y)) y <- list(relation = y) y <- complete_names(y, y.scales) y.scales[names(y)] <- y } if (is.logical(x.scales$alternating)) x.scales$alternating <- if (x.scales$alternating) c(1,2) else 1 if (is.logical(y.scales$alternating)) y.scales$alternating <- if (y.scales$alternating) c(1,2) else 1 for (nm in c("tck", "cex", "rot")) { x.scales[[nm]] <- rep(x.scales[[nm]], length.out = 2) y.scales[[nm]] <- rep(y.scales[[nm]], length.out = 2) } if (x.scales$relation == "same" && (is.list(x.scales$at) || is.list(x.scales$labels))) stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'") if (y.scales$relation == "same" && (is.list(y.scales$at) || is.list(y.scales$labels))) stop("the 'at' and 'labels' components of 'scales' may not be lists when 'relation = \"same\"'") list(x.scales = x.scales, y.scales = y.scales) } cupdate <- function(index, maxim) { ## This unexported function is used to handle arbitrary number of ## conditioning variables : every time it is called, it increments ## the "current" level of the conditioning variables suitably, ## i.e., it tries to increment the level of the 1st conditining ## variable (the one which varies fastest along panel order) and ## if it happens to be at its maximum (last) value, it sets it to ## the first value AND increments the "current" level of the 2nd ## (next) conditioning variable recursively. if(length(index)!=length(maxim)||length(maxim)<=0) stop("Inappropriate arguments") index[1] <- index[1] + 1 if (index[1] > maxim[1] && length(maxim) > 1) c(1, cupdate(index[-1], maxim[-1])) else index } limits.and.aspect <- function(prepanel.default, prepanel = NULL, have.xlim = FALSE, xlim = NULL, have.ylim = FALSE, ylim = NULL, x.relation, y.relation, panel.args.common = list(), panel.args = list(), aspect, banking = lattice.getOption("banking"), npackets = length(panel.args), x.axs = "r", y.axs = "r", ...) ## extra arguments for prepanel (for qqmathline) { prepanel.default.function <- getFunctionOrName(prepanel.default) prepanel <- getFunctionOrName(prepanel) if (npackets<1) stop("need at least one panel") x.limits <- vector("list", npackets) y.limits <- vector("list", npackets) x.used.at <- vector("list", npackets) y.used.at <- vector("list", npackets) x.num.limit <- vector("list", npackets) y.num.limit <- vector("list", npackets) dxdy <- vector("list", npackets) for (count in seq_len(npackets)) { if (is.list(panel.args[[count]])) { pargs <- c(panel.args.common, panel.args[[count]], list(...)) tem <- do.call("prepanel.default.function", pargs) if (is.function(prepanel)) ## results will 'overwrite' defaults { prenames <- names(formals(prepanel)) if (!("..." %in% prenames)) pargs <- pargs[intersect(names(pargs), prenames)] pretem <- do.call("prepanel", pargs) ## prepanel() over-rides defaults except NAs - e.g. ylim = c(0, NA) if (!is.null(pretem$xlim) && !is.character(pretem$xlim)) if (any(isna <- is.na(pretem$xlim))) pretem$xlim[isna] <- tem$xlim[isna] if (!is.null(pretem$ylim) && !is.character(pretem$ylim)) if (any(isna <- is.na(pretem$ylim))) pretem$ylim[isna] <- tem$ylim[isna] tem <- updateList(tem, pretem) ## tem[names(pretem)] <- pretem } x.limits[[count]] <- tem$xlim y.limits[[count]] <- tem$ylim x.used.at[[count]] <- if (is.null(tem$xat)) NA else tem$xat y.used.at[[count]] <- if (is.null(tem$yat)) NA else tem$yat x.num.limit[[count]] <- if (is.null(tem$xat)) NA else range(tem$xat) y.num.limit[[count]] <- if (is.null(tem$yat)) NA else range(tem$yat) dxdy[[count]] <- list(dx = tem$dx, dy = tem$dy) } else ## this happens for empty panels { x.limits[[count]] <- c(NA_real_, NA_real_) y.limits[[count]] <- c(NA_real_, NA_real_) x.used.at[[count]] <- NA_real_ y.used.at[[count]] <- NA_real_ x.num.limit[[count]] <- NA_real_ y.num.limit[[count]] <- NA_real_ dxdy[[count]] <- list(dx = NA_real_, dy = NA_real_) } } ## Some explanation might be helpful here. The for loop above ## creates a list of xlims/ylims. Each of these might be either ## numeric (when x/y is numeric, shingle or POSIXt etc), or levels ## of a factor (that's how prepanel.default.functions are set ## up). However, at this point, all x.limits[[i]] must be of the ## same type. Returned limits must be in accordance with this ## type. The only exception is when relation = "free", in which ## case they may be different. This could happen if [xy]lim or ## limits is supplied as a list in the high level function. x.limits <- limitsFromLimitlist(have.lim = have.xlim, lim = xlim, relation = x.relation, limitlist = x.limits, used.at = x.used.at, numlimitlist = x.num.limit, axs = x.axs, npackets = npackets) y.limits <- limitsFromLimitlist(have.lim = have.ylim, lim = ylim, relation = y.relation, limitlist = y.limits, used.at = y.used.at, numlimitlist = y.num.limit, axs = y.axs, npackets = npackets) if (is.character(aspect)) { if (aspect == "xy") { aspect <- median(sapply(dxdy, banking) * y.limits$slicelen / x.limits$slicelen, na.rm = TRUE) ### old aspect calculation ## aspect <- median(unlist(lapply(dxdy, banking)), ## na.rm = TRUE) * y.limits$slicelen / ## x.limits$slicelen ## if (y.relation == "free" || x.relation == "free") ## warning("'aspect=xy' when 'relation=free' is not sensible") } else if (aspect == "iso") { aspect <- median(y.limits$slicelen / x.limits$slicelen, na.rm = TRUE) if (y.relation == "free" || x.relation == "free") warning("'aspect=\"iso\"' approximate since 'relation=\"free\"'") } else aspect <- 1 } list(x.limits = x.limits$limits, y.limits = y.limits$limits, x.used.at = x.limits$used.at, y.used.at = y.limits$used.at, x.num.limit = x.limits$numlimitlist, y.num.limit = y.limits$numlimitlist, aspect.ratio = aspect, prepanel.default = prepanel.default, prepanel = prepanel) } hexbin/R/grid.hexlegend.R0000644000175100001440000001375311551510077014773 0ustar hornikusersgrid.hexlegend <- function(legend, ysize, lcex, inner, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, leg.unit="native") { ## the formal arg matching should happen style <- match.arg(style, eval(formals(grid.hexagons)[["style"]])) if (style %in% c("centroids", "lattice", "colorscale")) { ## _______________tranformations_______________________ if(is.null(trans)) { sc <- maxcnt - mincnt bnds <- round(mincnt + sc * colorcut) } else { if(!is.function(trans) && !is.function(inv)) stop("'trans' and 'inv' must both be functions if 'trans' is not NULL") con <- trans(mincnt) sc <- trans(maxcnt) - con bnds <- round(inv(con + sc * colorcut)) } } if(style == "colorscale") { ## use own 'inner' n <- length(bnds) spacing <- ysize/(n + 3) inner <- min(legend/3.5, (sqrt(3) * spacing)/2) } dx <- inner/2 dy <- dx/sqrt(3) hexC <- hexcoords(dx, dy, n = 1,sep=NULL) ## _______________Plotting______________________________ switch(style, "colorscale" = { midx <- legend/3 textx <- (2 * legend)/3 tx <- hexC$x + midx pen <- colramp(n) for(i in seq(length = n-1)) { grid.polygon(tx,hexC$y + i * spacing, default.units=leg.unit,id=NULL,id.lengths=6, gp=gpar(fill = pen[i], col = border)) grid.text(as.character(bnds[i]), textx, (i - 0.5) * spacing, default.units=leg.unit, gp=gpar(cex = lcex)) } grid.text(as.character(bnds[n]), textx, (n - 0.5) * spacing, default.units=leg.unit, gp=gpar(cex = lcex)) grid.text("Counts", legend/2, (n + 1.5) * spacing, default.units=leg.unit, gp=gpar(cex = 1.7 * lcex)) }, "centroids" = , "lattice" = { ## NL Solved hex overlap problem on legend ## Need to tackle too many categories radius <- sqrt(minarea + (maxarea - minarea) * colorcut) n <- length(radius) shift <- c(0, 2*dy*radius) shift <- shift[1:n] + shift[2:(n+1)] #labht <- max(strheight(as.character(bnds), cex = lcex)) labht <- convertY(unit(get.gpar(names = "fontsize")[[1]]*lcex, "points"),"native",valueOnly = TRUE) shift <- pmax(labht, shift) six <- rep.int(6:6, n) xmid <- legend/3 inc <- ysize/(n+3) if(inc > max(shift)) y <- inc * 1:n else { y <- cumsum(shift) extra.slop <- (n * inc) - y[n] # FIXME? y[n] == sum(shift) shift[-1] <- shift[-1] + extra.slop/(n-1) y <- cumsum(shift) ## (y+(1/n)*extra.slop)-y[1] ## delta <- max(log(shift))-min(log(shift)) ## fudge <- extra.slop*(diff(log(shift))/delta) ## y<- c(y[1], y[-1]+ fudge ) } textx <- rep.int((2 * legend)/3, n) ## ____________________plotting______________________ if(is.null(pen)) pen <- 1 if(is.null(border)) border <- pen grid.polygon(x = rep.int(hexC$x,n)* rep.int(radius, six) + rep.int(xmid, 6 * n), y = rep.int(hexC$y,n)* rep.int(radius, six) + rep.int(y, six), default.units=leg.unit, id=NULL, id.lengths=rep.int(6,n), gp=gpar(fill = pen, col = border)) grid.text(as.character(bnds), textx, y, default.units=leg.unit, gp=gpar(cex = lcex)) grid.text("Counts", legend/2, (n + 2) * inc, default.units=leg.unit, gp=gpar(cex =1.7 * lcex)) }, "nested.lattice" = , "nested.centroids" = { ## _____________x scaling_____________________________ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4)) ## Note: In old code ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9 if(is.na(numb)) numb <- 4 switch(numb, {warning("not enough space for legend"); return()}, size <- 5, size <- c(1, 5, 9), size <- c(1, 3, 5, 7, 9)) xmax <- length(size) radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9) txt <- as.character(size) ##___________________y scaling_____________________ lab <- c("Ones", "Tens", "Hundreds", "Thousands", "10 Thousands", "100 Thousands", "Millions", "10 Millions", "100 Millions", "Billions") power <- floor(log10(maxcnt)) + 1 yinc <- 16 * dy if(ysize/power < yinc) {warning("Not enough height for legend"); return()} xmid <- legend/10 x <- inner * (1:xmax - (1 + xmax)/2) + xmid n <- length(x) tx <- rep.int(hexC$x, n) ty <- rep.int(hexC$y, n) six <- rep.int(6:6, n) y <- rep.int(3 * dy - yinc, xmax) ## ____________________plotting______________________ if(is.null(pen)) { pen <- 1:power +1 pen <- cbind(pen, pen +10) } if(is.null(border)) border <- FALSE for(i in 1:power) { y <- y + yinc hexpolygon(x, y, hexC, col = pen[i,1], border = border) grid.polygon(x= tx * rep.int(radius, six) + rep.int(x, six), y= ty * rep.int(radius, six) + rep.int(y, six), default.units=leg.unit, id=NULL, id.lengths=rep(6,n), gp=gpar(fill = pen[i,2], col = border)) grid.text(txt, x, y - 4.5 * dy, default.units=leg.unit, gp=gpar(cex = lcex)) ##adj= 0.5, cex = lcex) grid.text(lab[i], xmid, y[1] + 4.5 * dy, default.units=leg.unit, gp=gpar(cex = 1.7*lcex)) ##adj= 0.5, cex = 1.7*lcex) } })## switch(style = *) }## hex.legend() hexbin/R/hexpanel.R0000644000175100001440000000267512102123310013670 0ustar hornikuserspanel.hexloess <- function(bin, w=NULL, span = 2/3, degree = 1, family = c("symmetric", "gaussian"), evaluation = 50, lwd = add.line$lwd, lty = add.line$lty, col, col.line = add.line$col, ...) { stop("panel.hexloess is no longer available") add.line <- trellis.par.get("add.line") ## x <- bin@xcm ## y <- bin@ycm ## if(is.null(w))w <- bin@count ## control <- loess.control(...) ## notna <- !(is.na(x) | is.na(y)) ## new.x <- seq(min(x[notna]), max(x[notna]), length = evaluation) ## family <- match.arg(family) ## iterations <- if (family == "gaussian") 1 else control$iterations ## fit <- stats:::simpleLoess(y, x, w, span, degree, FALSE, FALSE, ## normalize = FALSE, "none", "interpolate", ## control$cell, iterations, control$trace.hat) ## kd <- fit$kd ## z <- .C("loess_ifit", as.integer(kd$parameter), as.integer(kd$a), ## as.double(kd$xi), as.double(kd$vert), as.double(kd$vval), ## as.integer(evaluation), as.double(x), fit = double(evaluation), ## PACKAGE = "stats")$fit ## if (length(x) > 0) { ## if (!missing(col) && missing(col.line)) { ## col.line <- col ## } ## add.line <- trellis.par.get("add.line") ## panel.lines(new.x, z, col = col.line, lty = lty, lwd = lwd) ## } } panel.hexgrid <- function(h, border=grey(.85)) { hexGraphPaper(h,border=border) } hexbin/R/hexPlotMA.R0000644000175100001440000001654312546727117013757 0ustar hornikusersplotMAhex <- function (MA, array = 1, xlab = "A", ylab = "M", main = colnames(MA)[array], xlim = NULL, ylim = NULL, status = NULL, values, pch, col, cex, nbin=40, zero.weights = FALSE, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 2, maxcnt = NULL, trans = NULL, inv = NULL, colorcut = NULL, border = NULL, density = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90,end = 15) }, newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), verbose = getOption("verbose")) { if (!requireNamespace("marray", quietly = TRUE)) stop("cannot process objects without package marray") if (!requireNamespace("limma", quietly = TRUE)) stop("cannot process objects without package limma") if(is.null(main))main <- "" switch(class(MA),marrayRaw={ x <- marray::maA(MA[,array]) y <- marray::maM(MA[,array]) w <- marray::maW(MA[,array]) },RGList = { MA <- limma::MA.RG(MA[, array]) array <- 1 x <- MA$A y <- MA$M w <- MA$w }, MAList = { x <- as.matrix(MA$A)[, array] y <- as.matrix(MA$M)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, list = { if (is.null(MA$A) || is.null(MA$M)) stop("No data to plot") x <- as.matrix(MA$A)[, array] y <- as.matrix(MA$M)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, MArrayLM = { x <- MA$Amean y <- as.matrix(MA$coefficients)[, array] if (is.null(MA$weights)) w <- NULL else w <- as.matrix(MA$weights)[, array] }, matrix = { narrays <- ncol(MA) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(MA, 1, median, na.rm = TRUE) else x <- rowMeans(MA, na.rm = TRUE) y <- MA[, array] - x w <- NULL }, ExpressionSet = { if (!requireNamespace("Biobase", quietly = TRUE)) stop("cannot process ExpressionSet objects without package Biobase") narrays <- ncol(Biobase::exprs(MA)) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(Biobase::exprs(MA), 1, median, na.rm = TRUE) else x <- rowMeans(Biobase::exprs(MA), na.rm = TRUE) y <- Biobase::exprs(MA)[, array] - x w <- NULL if (missing(main)) main <- colnames(Biobase::exprs(MA))[array] }, AffyBatch = { if (!requireNamespace("Biobase", quietly = TRUE) || !requireNamespace("affy", quietly = TRUE)) stop("cannot process AffyBatch objects without package Biobase and affy") narrays <- ncol(Biobase::exprs(MA)) if (narrays < 2) stop("Need at least two arrays") if (narrays > 5) x <- apply(log2(Biobase::exprs(MA)), 1, median, na.rm = TRUE) else x <- rowMeans(log2(Biobase::exprs(MA)), na.rm = TRUE) y <- log2(Biobase::exprs(MA)[, array]) - x w <- NULL if (missing(main)) main <- colnames(Biobase::exprs(MA))[array] }, stop("MA is invalid object")) if (!is.null(w) && !zero.weights) { i <- is.na(w) | (w <= 0) y[i] <- NA } if (is.null(xlim)) xlim <- range(x, na.rm = TRUE) if (is.null(ylim)) ylim <- range(y, na.rm = TRUE) hbin <- hexbin(x,y,xbins=nbin,xbnds=xlim,ybnds=ylim, IDs = TRUE) hp <- plot(hbin, legend=legend, xlab = xlab, ylab = ylab, main = main, type='n', newpage=newpage) ## plot the hexagons pushHexport(hp$plot.vp) if(is.null(maxcnt)) maxcnt <- max(hbin@count) if(is.null(colorcut)) colorcut<-seq(0, 1, length = min(17, maxcnt)) grid.hexagons(hbin, style=style, minarea = minarea, maxarea = maxarea, mincnt = mincnt, maxcnt= maxcnt, trans = trans, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) if (is.null(status) || all(is.na(status))) { if (missing(pch)) pch <- 16 if (missing(cex)) cex <- 0.3 if (missing(col)) { clrs <- colramp(length(colorcut)-1) col <- clrs[1] } pp <- inout.hex(hbin,mincnt) grid.points(x[pp], y[pp], pch = pch[[1]], gp=gpar(cex = cex[1], col=col, fill=col)) } else { if (missing(values)) { if (is.null(attr(status, "values"))) values <- names(sort(table(status), decreasing = TRUE)) else values <- attr(status, "values") } sel <- !(status %in% values) nonhi <- any(sel) if (nonhi) grid.points(x[sel], y[sel], pch = 16, gp=gpar(cex = 0.3)) nvalues <- length(values) if (missing(pch)) { if (is.null(attr(status, "pch"))) pch <- rep(16, nvalues) else pch <- attr(status, "pch") } if (missing(cex)) { if (is.null(attr(status, "cex"))) { cex <- rep(1, nvalues) if (!nonhi) cex[1] <- 0.3 } else cex <- attr(status, "cex") } if (missing(col)) { if (is.null(attr(status, "col"))) { col <- nonhi + 1:nvalues } else col <- attr(status, "col") } pch <- rep(pch, length = nvalues) col <- rep(col, length = nvalues) cex <- rep(cex, length = nvalues) for (i in 1:nvalues) { sel <- status == values[i] grid.points(x[sel], y[sel], pch = pch[[i]], gp=gpar(cex = cex[i], col = col[i])) } } popViewport() if (legend > 0) { inner <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[1] inner <- inner/hbin@xbins ysize <- getPlt(hp$plot.vp, ret.unit="inches", numeric=TRUE)[2] pushViewport(hp$legend.vp) grid.hexlegend(legend, ysize=ysize, lcex = lcex, inner = inner, style= style, minarea= minarea, maxarea= maxarea, mincnt= mincnt, maxcnt= maxcnt, trans=trans, inv=inv, colorcut = colorcut, density = density, border = border, pen = pen, colramp = colramp) #if (is.list(pch)) # legend(x = xlim[1], y = ylim[2], legend = values, # fill = col, col = col, cex = 0.9) #else legend(x = xlim[1], y = ylim[2], legend = values, # pch = pch, , col = col, cex = 0.9) popViewport() } invisible(list(hbin = hbin, plot.vp = hp$plot.vp, legend.vp = hp$legend.vp)) } hexMA.loess <- function(pMA, span = .4, col = 'red', n = 200) { fit <- hexVP.loess(pMA$hbin, pMA$plot.vp, span = span, col = col, n = n) invisible(fit) } hexbin/R/RB.R0000644000175100001440000002001411551510077012373 0ustar hornikusersplinrain <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c( 0, 0, 0), c( 45, 0, 36), c( 56, 0, 46), c( 60, 0, 49), c( 67, 0, 54), c( 70, 0, 59), c( 71, 0, 61), c( 75, 0, 68), c( 74, 0, 73), c( 74, 0, 77), c( 73, 0, 81), c( 71, 0, 87), c( 69, 1, 90), c( 68, 2, 94), c( 66, 3, 97), c( 63, 6,102), c( 61, 7,106), c( 58, 10,109), c( 56, 12,113), c( 53, 15,116), c( 48, 18,119), c( 47, 20,121), c( 44, 23,124), c( 41, 27,128), c( 40, 28,129), c( 37, 32,132), c( 34, 36,134), c( 29, 43,137), c( 25, 52,138), c( 24, 57,139), c( 24, 62,141), c( 24, 64,142), c( 23, 65,142), c( 23, 69,143), c( 23, 71,142), c( 23, 71,142), c( 23, 73,142), c( 23, 75,142), c( 23, 75,142), c( 23, 78,142), c( 23, 80,142), c( 23, 80,142), c( 23, 82,141), c( 23, 85,141), c( 23, 85,141), c( 23, 87,140), c( 23, 87,140), c( 24, 90,140), c( 24, 90,140), c( 24, 93,139), c( 24, 93,139), c( 24, 93,139), c( 24, 93,139), c( 24, 97,139), c( 24, 97,139), c( 25,101,138), c( 25,101,138), c( 25,104,137), c( 25,104,137), c( 25,104,137), c( 26,108,137), c( 26,108,137), c( 27,111,136), c( 27,111,136), c( 27,111,136), c( 27,115,135), c( 27,115,135), c( 28,118,134), c( 28,118,134), c( 29,122,133), c( 29,122,133), c( 29,122,133), c( 29,122,133), c( 29,125,132), c( 29,125,132), c( 30,128,131), c( 30,128,131), c( 31,131,130), c( 31,131,130), c( 31,131,130), c( 32,134,128), c( 32,134,128), c( 33,137,127), c( 33,137,127), c( 33,137,127), c( 34,140,125), c( 34,140,125), c( 35,142,123), c( 35,142,123), c( 36,145,121), c( 36,145,121), c( 36,145,121), c( 37,147,118), c( 37,147,118), c( 38,150,116), c( 38,150,116), c( 40,152,113), c( 40,152,113), c( 41,154,111), c( 41,154,111), c( 42,156,108), c( 42,156,108), c( 43,158,106), c( 43,158,106), c( 43,158,106), c( 45,160,104), c( 45,160,104), c( 46,162,101), c( 46,162,101), c( 48,164, 99), c( 48,164, 99), c( 50,166, 97), c( 50,166, 97), c( 51,168, 95), c( 53,170, 93), c( 53,170, 93), c( 53,170, 93), c( 55,172, 91), c( 55,172, 91), c( 57,174, 88), c( 57,174, 88), c( 59,175, 86), c( 62,177, 84), c( 64,178, 82), c( 64,178, 82), c( 67,180, 80), c( 67,180, 80), c( 69,181, 79), c( 72,183, 77), c( 72,183, 77), c( 72,183, 77), c( 75,184, 76), c( 77,186, 74), c( 80,187, 73), c( 83,189, 72), c( 87,190, 72), c( 91,191, 71), c( 95,192, 70), c( 99,193, 70), c(103,194, 70), c(107,195, 70), c(111,196, 70), c(111,196, 70), c(115,196, 70), c(119,197, 70), c(123,197, 70), c(130,198, 71), c(133,199, 71), c(137,199, 72), c(140,199, 72), c(143,199, 73), c(143,199, 73), c(147,199, 73), c(150,199, 74), c(153,199, 74), c(156,199, 75), c(160,200, 76), c(167,200, 78), c(170,200, 79), c(173,200, 79), c(173,200, 79), c(177,200, 80), c(180,200, 81), c(183,199, 82), c(186,199, 82), c(190,199, 83), c(196,199, 85), c(199,198, 85), c(199,198, 85), c(203,198, 86), c(206,197, 87), c(212,197, 89), c(215,196, 90), c(218,195, 91), c(224,194, 94), c(224,194, 94), c(230,193, 96), c(233,192, 98), c(236,190,100), c(238,189,104), c(240,188,106), c(240,188,106), c(242,187,110), c(244,185,114), c(245,184,116), c(247,183,120), c(248,182,123), c(248,182,123), c(250,181,125), c(251,180,128), c(252,180,130), c(253,180,133), c(253,180,133), c(254,180,134), c(254,179,138), c(255,179,142), c(255,179,145), c(255,179,145), c(255,179,152), c(255,180,161), c(255,180,164), c(255,180,167), c(255,180,167), c(255,181,169), c(255,181,170), c(255,182,173), c(255,183,176), c(255,183,176), c(255,184,179), c(255,185,179), c(255,185,182), c(255,186,182), c(255,186,182), c(255,187,185), c(255,188,185), c(255,189,188), c(255,189,188), c(255,190,188), c(255,191,191), c(255,192,191), c(255,194,194), c(255,194,194), c(255,197,197), c(255,198,198), c(255,200,200), c(255,201,201), c(255,201,201), c(255,202,202), c(255,203,203), c(255,205,205), c(255,206,206), c(255,206,206), c(255,208,208), c(255,209,209), c(255,211,211), c(255,215,215), c(255,216,216), c(255,216,216), c(255,218,218), c(255,219,219), c(255,221,221), c(255,223,223), c(255,226,226), c(255,228,228), c(255,230,230), c(255,230,230), c(255,232,232), c(255,235,235), c(255,237,237), c(255,240,240), c(255,243,243), c(255,246,246), c(255,249,249), c(255,251,251), c(255,253,253), c(255,255,255))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexbinplot.R0000644000175100001440000007317512102122137014251 0ustar hornikusers## lattice version of gplot.hexbin ## There are two major problems. (1) For comparability across panels, ## we want the same mincnt and maxcnt in all panels. However, a ## suitable default can really only be determined at printing time, ## since it would depend on the physical dimensions of the panel. (2) ## there is no proper way to communicate the mincnt and maxcnt to the ## legend. ## Tentative solution: the counts can be calculated once enough things ## are known, namely the aspect ratio, xbins and [xy]bnds. An ## important question then is whether [xy]bnds should be [xy]lim or ## range([xy]). Both should be allowed, since [xy]lim makes them ## comparable, range([xy]) potentially shows more detail. For ## relation != "same", both are more or less similar. An important ## observation is that with range([xy]), 'shape = aspect ratio of ## panel' does not guarantee symmetric hexagons, so shape has to be ## different for each panel. ## Only feasible approach I can think of is to produce the trellis ## object first (with known aspect, so aspect="fill" is absolutely ## no-no), then analyze the limits and relevant panel arguments to get ## 'maxcnt' (essentially doing a dry run of the panel calculations). ## This needs undocumented knowledge of the trellis object, which is ## kinda not good, but at least it gets the job done. Once we know ## maxcnt, we can also set up a suitable legend function. ## Unfortunately, this has the potential to screw up update calls that ## modify certain things. Is there any way to capture those? Maybe ## make a new class that inherits from "trellis". For now, we'll ## pretend that the problem doesn't exist. ## tool borrowed from lattice updateList <- function (x, val) { if (is.null(x)) x <- list() modifyList(x, val) } prepanel.hexbinplot <- function(x, y, type = character(0),...) { if('tmd'%in%type){ tmp <- x x <- (y + x)/sqrt(2) y <- (y - tmp)/sqrt(2) } ans <- list(xlim = range(x, finite = TRUE), ylim = range(y, finite = TRUE), dx = IQR(x,na.rm=TRUE), dy = IQR(y,na.rm=TRUE)) } panel.hexbinplot <- function(x, y, ..., groups = NULL) { if (is.null(groups)) panel.hexbin(x, y, ...) else panel.hexpose(x, y, ..., groups = groups) } panel.hexbin <- function(x, y, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, # default useful with splom(, panel = panel.hexbin) type = character(0), ..., check.erosion = FALSE) { if ("tmd" %in% type) { tmp <- x x <- (y + x)/sqrt(2) y <- (y - tmp)/sqrt(2) } if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (!missing(check.erosion)) warning("explicit 'check.erosion' specification ignored") h <- hexbin(x = x, y = y, xbins = xbins, shape = shape, xbnds = xbnds, ybnds = ybnds) if (.prelim) return(max(h@count)) ## have to do this because grid.hexagons croaks with unrecognized ## arguments: args <- list(dat = h, check.erosion = FALSE, ...) keep <- names(args) %in% names(formals(grid.hexagons)) if ('g' %in% type) panel.grid(h = -1, v = -1) if ('hg' %in% type) panel.hexgrid(h) do.call("grid.hexagons", args[keep]) if ("r" %in% type) panel.lmline(x, y, ...) if ("smooth" %in% type) panel.hexloess(h,...) invisible() } panel.hexboxplot <- function(x, y, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, type = character(0), cdfcut=.25, shadow=.05, ..., check.erosion = TRUE) { if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (!missing(check.erosion)) warning("explicit 'check.erosion' specification ignored") h <-hexbin(x = x, y = y, xbins = xbins, shape = shape, xbnds = xbnds, ybnds = ybnds,IDs=TRUE) if (.prelim) return(max(h@count)) ## have to do this because grid.hexagons croaks with unrecognized ## arguments: args <- list(dat = h, check.erosion = FALSE, ...) keep <- names(args) %in% names(formals(grid.hexagons)) if ('hg' %in% type) panel.hexgrid(h) if ('g' %in% type) panel.grid(h = -1, v = -1) if(shadow) { eh <- erode(h,cdfcut=shadow) h.xy <- hcell2xy(eh,check.erosion=TRUE) dx <- (0.5 * diff(eh@xbnds))/eh@xbins dy <- (0.5 * diff(eh@ybnds))/(eh@xbins * h@shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) hexpolygon(h.xy$x,h.xy$y, hexC, density = density, fill = NA, border = gray(.75)) } eh <- erode(h,cdfcut=cdfcut) h.xy <- hcell2xy(eh,check.erosion=TRUE) dx <- (0.5 * diff(eh@xbnds))/eh@xbins dy <- (0.5 * diff(eh@ybnds))/(eh@xbins * h@shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) hexpolygon(h.xy$x,h.xy$y, hexC, density = density, fill = "green", border = gray(.75)) med <- which.max(eh@erode) xnew <- h.xy$x[med] ynew <- h.xy$y[med] hexpolygon(xnew, ynew, hexC, density = density, fill = "red", border =gray(.25)) invisible() } panel.hexpose <- function(x, y, groups, subscripts, xbins = 30, xbnds = c("data", "panel"), # was: xbnds = c("panel", "data"), ybnds = c("data", "panel"), # was: ybnds = c("panel", "data"), ## special args .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio = 1, #erode Args cdfcut=.05, #hdiff Args hexpose.focus=c(1,2), hexpose.focus.colors=c("yellow","blue"), hexpose.focus.border=c("cyan","orange"), hexpose.median.color="red", hexpose.median.border="black", arrows = TRUE, size = unit(0.1, "inches"), arrow.lwd = 2, eps = 1e-6, type = character(0), ..., check.erosion = TRUE) { if (is.character(xbnds)) xbnds <- switch(match.arg(xbnds), panel = .xlim, data = range(x, finite = TRUE)) if (is.character(ybnds)) ybnds <- switch(match.arg(ybnds), panel = .ylim, data = range(y, finite = TRUE)) shape <- .aspect.ratio * (diff(ybnds) / diff(.ylim)) / (diff(xbnds) / diff(.xlim)) if (is.numeric(groups)) groups <- as.character(groups[subscripts]) else groups <- groups[subscripts] binL <- hexList(x, y, given=groups, xbins=xbins, shape=shape, xbnds=xbnds, ybnds=ybnds) if ('hs' %in% type) lapply(binL@hbins,smooth.hexbin) binL@hbins <- lapply(binL@hbins,erode,cdfcut=cdfcut) if ('hg' %in% type) panel.hexgrid(binL@hbins[[1]]) ## ??? if ('g' %in% type) panel.grid(h = -1, v = -1) eroded <- unlist(lapply(binL@hbins, is, "erodebin")) tmph.xy <- lapply(binL@hbins, hcell2xy, check.erosion = TRUE) ##__________________ Construct hexagon___________________ dx <- (0.5 * diff(binL@Xbnds))/xbins dy <- (0.5 * diff(binL@Ybnds))/(xbins * binL@Shape * sqrt(3)) hexC <- hexcoords(dx = dx, dy = dy) ##__________________ Set up intersections and colors___________________ ## Reorder so that the focus bin objects are at the top of the list if(length(hexpose.focus) < binL@n) { binL@hbins <- c(binL@hbins[hexpose.focus], binL@hbins[-hexpose.focus]) binL@Bnames <- c(binL@Bnames[hexpose.focus], binL@Bnames[-hexpose.focus]) } cell.stat <- all.intersect(binL@hbins) cell.stat.n <- apply(cell.stat, 1, sum) i.depth <- max(cell.stat.n) diff.cols <- vector(mode = "list", length = i.depth) levcells <- which(cell.stat.n == 1) whichbin <- apply(cell.stat[levcells, ], 1, which) ## Set all the focal colors for the unique bin cells ## if not specified make them equally spaced on the color wheel ## with high saturation and set the background bins to gray nfcol <- length(hexpose.focus) nhb <- binL@n nbcol <- nhb-nfcol fills <- if(is.null(hexpose.focus.colors)) { if(nbcol > 0) hsv(h = c(seq(0, 1, length = nfcol+1)[1:nfcol],rep(0, nbcol)), s = c(rep(1, nfcol), rep(0, nbcol)), ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol)) v = c(rep(1, nfcol), rep(.9, nbcol))) else hsv(h=seq(0, 1, length = nhb+1))[1:nfcol] } else { foc.col <- t(col2rgb(hexpose.focus.colors))/255 if(nbcol > 0) { bcol <- t(col2rgb(rep(grey(.6),nbcol)))/255 rbind(foc.col, bcol) } else foc.col } diff.cols[[1]] <- list(fill = fills, border = gray(.8)) ##_______________ Full Cell Plotting for Unique BinL Cells_________________ if(length(levcells) > 0) { for(i in unique(whichbin)) { pcells <- if(eroded[i]) binL@hbins[[i]]@cell[binL@hbins[[i]]@eroded] else binL@hbins[[i]]@cell pcells <- which(pcells %in% levcells[whichbin == i]) hexpolygon(x = tmph.xy[[i]]$x[pcells], y = tmph.xy[[i]]$y[pcells], hexC, border = hexpose.focus.border[i] , fill = hexpose.focus.colors[i] ) } } ## Now do the intersections. All intersections are convex ## combinations of the colors of the overlapping unique bins in ## the CIEluv colorspace. so if the binlist is of length 2 and ## the focal hbins are "blue" and "yellow" respectively the ## intersection would be green. First I need to get this to work ## and then I can think about how to override this with an option ## in color.control. -NL if(i.depth > 1) { for(dl in 2:(i.depth)) { levcells <- which(cell.stat.n == dl) if(length(levcells) == 0) next whichbin <- apply(cell.stat[levcells, ], 1, function(x)paste(which(x), sep = "", collapse = ":")) inter.nm <- unique(whichbin) fills <- matrix(0, length(inter.nm), 3) i <- 1 for(bn in inter.nm) { who <- as.integer(unlist(strsplit(bn, ":"))) ## FIXME (DS): this doesn't work fills[i, ] <- mixcolors2(1/length(who), diff.cols[[1]]$fill[who,]) i <- i+1 } fills <- rgb(fills[,1],fills[,2],fills[,3]) diff.cols[[dl]] <- list(fill = fills, border = gray((i.depth-dl)/i.depth)) ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____ i <- 1 for(ints in inter.nm) { bin.i <- as.integer(unlist(strsplit(ints, ":"))[1]) pcells <- if(eroded[bin.i]) binL@hbins[[bin.i]]@cell[binL@hbins[[bin.i]]@eroded] else binL@hbins[[bin.i]]@cell pcells <- which(pcells %in% levcells[whichbin == ints]) hexpolygon(x = tmph.xy[[bin.i]]$x[pcells], y = tmph.xy[[bin.i]]$y[pcells], hexC, border = diff.cols[[dl]]$border , fill = diff.cols[[dl]]$fill[i] ) i <- i+1 } } } if(any(eroded)) { hmeds <- matrix(unlist(lapply(binL@hbins[eroded], function(x)unlist(getHMedian(x)))), ncol = 2, byrow = TRUE) hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC, border = hexpose.median.border, fill = hexpose.median.color) if(arrows) { for(i in hexpose.focus) { for(j in hexpose.focus[hexpose.focus < i]) { if(abs(hmeds[i, 1] - hmeds[j, 1]) + abs(hmeds[i, 2] - hmeds[j, 2]) > eps) grid.arrows(c(hmeds[i, 1], hmeds[j, 1]), c(hmeds[i, 2], hmeds[j, 2]), default.units = "native", length = size, gp = gpar(lwd = arrow.lwd)) } } } } invisible() } hexbinplot <- function(x, data, ...) UseMethod("hexbinplot") hexbinplot.formula <- function(x, data = NULL, prepanel = prepanel.hexbinplot, panel = panel.hexbinplot, groups = NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, ..., maxcnt, legend = NULL, legend.width = TRUE, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexbinplot) ccall <- match.call() if (is.logical(legend.width)) legend.width <- 1.2 * as.numeric(legend.width) if (is.character(aspect) && aspect == "fill") stop("aspect = 'fill' not permitted") if (!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation 'inv'") ccall$data <- data ccall$prepanel <- prepanel ccall$panel <- panel ccall$aspect <- aspect ccall$trans <- trans ccall$inv <- inv ccall$legend <- legend ccall[[1]] <- quote(lattice::xyplot) ans <- eval(ccall, parent.frame()) ## panel needs to know aspect ratio to calculate shape ans <- update(ans, .aspect.ratio = ans$aspect.ratio) ## also need maxcnt, o.w. can't draw legend, panels not comparable ## either if (missing(maxcnt)) maxcnt <- max(mapply(panel.hexbinplot, ## note: not 'panel' x = lapply(ans$panel.args, "[[", "x"), y = lapply(ans$panel.args, "[[", "y"), .xlim = if (is.list(ans$x.limits)) ans$x.limits else rep(list(ans$x.limits), length(ans$panel.args)), .ylim = if (is.list(ans$y.limits)) ans$y.limits else rep(list(ans$y.limits), length(ans$panel.args)), MoreArgs = c(ans$panel.args.common, list(.prelim = TRUE, .cpl = NA)))) ans <- update(ans, maxcnt = maxcnt) if (colorkey) ans <- update(ans, legend = updateList(ans$legend, list(right = list(fun = hexlegendGrob, args = list(maxcnt = maxcnt, trans = trans, inv = inv, legend = legend.width, ...))))) ans$call <- ocall ans } old.hexbinplot.formula <- function(x, data = parent.frame(), prepanel = prepanel.hexbinplot, panel = if (is.null(groups)) panel.hexbinplot else panel.hexpose, groups=NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, ..., maxcnt, legend = NULL, legend.width = TRUE) { if (is.logical(legend.width)) legend.width <- 1.2 * as.numeric(legend.width) if (is.character(aspect) && aspect == "fill") stop("aspect = 'fill' not permitted") if (!is.null(trans) && is.null(inv)) stop("Must supply the inverse transformation 'inv'") groups <- eval(substitute(groups), data, parent.frame()) ## There must be a better way to handle this, ugh. ans <- if(is.null(groups)) { xyplot(x, data = data, prepanel = prepanel, panel = panel, aspect = aspect, trans = trans, inv = inv, legend = legend, ...) } else { xyplot(x, data = data, prepanel = prepanel, panel = panel, groups=groups, aspect = aspect, trans = trans, inv = inv, legend = legend, ...) } ## panel needs to know aspect ratio to calculate shape ans <- update(ans, .aspect.ratio = ans$aspect.ratio) ## also need maxcnt, o.w. can't draw legend, panels not comparable ## either if (missing(maxcnt)) maxcnt <- max(mapply(panel.hexbinplot, ## note: not 'panel' x = lapply(ans$panel.args, "[[", "x"), y = lapply(ans$panel.args, "[[", "y"), .xlim = if (is.list(ans$x.limits)) ans$x.limits else rep(list(ans$x.limits), length(ans$panel.args)), .ylim = if (is.list(ans$y.limits)) ans$y.limits else rep(list(ans$y.limits), length(ans$panel.args)), MoreArgs = c(ans$panel.args.common, list(.prelim = TRUE, .cpl = NA)))) ans <- update(ans, maxcnt = maxcnt) if (colorkey) ans <- update(ans, legend = updateList(ans$legend, list(right = list(fun = hexlegendGrob, args = list(maxcnt = maxcnt, trans = trans, inv = inv, legend = legend.width, ...))))) ans } ## want a grob instead of actual plotting hexlegendGrob <- function(legend = 1.2, inner = legend / 5, cex.labels = 1, cex.title = 1.2, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, ..., vp = NULL, draw = FALSE) { ## the formal arg matching should happen style <- match.arg(style, eval(formals(grid.hexagons)[["style"]])) if (style %in% c("centroids", "lattice", "colorscale")) { ## _______________tranformations_______________________ if(is.null(trans)) { sc <- maxcnt - mincnt bnds <- round(mincnt + sc * colorcut) } else { if(!is.function(trans) && !is.function(inv)) stop("'trans' and 'inv' must both be functions if 'trans' is not NULL") con <- trans(mincnt) sc <- trans(maxcnt) - con bnds <- round(inv(con + sc * colorcut)) } } ## grob ans <- switch(style, "colorscale" = { n <- length(bnds) pen <- colramp(n-1) ## rectangles instead of polygons ## pol <- ## rectGrob(x = 0.5, y = 1:(n-1)/n, ## height = 1/n, ## default.units = "npc", ## gp = gpar(fill = pen, col = border)) hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")] maxxy <- max(abs(unlist(hexxy))) hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy) pol <- polygonGrob(x = 0.5 + rep(hexxy$x, n-1), y = (rep(1:(n-1), each = 6) + hexxy$y) / n, id.lengths = rep(6, n-1), gp = gpar(fill = pen, col = border), default.units = "npc") txt <- textGrob(as.character(bnds), x = 0.5, y = (0:(n-1) + 0.5) / n, gp = gpar(cex = cex.labels), default.units = "npc") ttl <- textGrob("Counts", gp = gpar(cex = cex.title)) key.layout <- grid.layout(nrow = 2, ncol = 2, heights = unit(c(1.5, 1), c("grobheight", "grobheight"), data = list(ttl, txt)), widths = unit(c(1/n, 1), c("grobheight", "grobwidth"), data = list(pol, txt)), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2) key.gf <- placeGrob(key.gf, pol, row = 2, col = 1) key.gf <- placeGrob(key.gf, txt, row = 2, col = 2) key.gf }, "centroids" = , "lattice" = { warning("legend shows relative sizes") ## Note: it may not be impossible to get absolute ## sizes. The bigger problem is that when ## [xy]bnds="data", the sizes (for the same count) may ## not be the same across panels. IMO, that's a more ## useful feature than getting the absolute sizes ## right. radius <- sqrt(minarea + (maxarea - minarea) * colorcut) n <- length(radius) if(is.null(pen)) pen <- 1 if(is.null(border)) border <- pen hexxy <- hexcoords(dx = 1, n = 1)[c("x", "y")] maxxy <- max(abs(unlist(hexxy))) hexxy <- lapply(hexxy, function(x) 0.5 * x/ maxxy) pol <- polygonGrob(x = 0.5 + rep(radius, each = 6) * rep(hexxy$x, n), y = (rep(0.5 + 1:n, each = 6) + rep(radius, each = 6) * hexxy$y - 1) / n, id.lengths = rep(6, n), gp = gpar(fill = pen, col = border), default.units = "npc") txt <- textGrob(as.character(bnds), x = 0.5, y = (1:n - 0.5) / n, gp = gpar(cex = cex.labels), default.units = "npc") ttl <- textGrob("Counts", gp = gpar(cex = cex.title)) key.layout <- grid.layout(nrow = 2, ncol = 2, heights = unit(c(1.5, 1), c("grobheight", "grobheight"), data = list(ttl, txt)), widths = unit(c(1/n, 1), c("grobheight", "grobwidth"), data = list(pol, txt)), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) key.gf <- placeGrob(key.gf, ttl, row = 1, col = 1:2) key.gf <- placeGrob(key.gf, pol, row = 2, col = 1) key.gf <- placeGrob(key.gf, txt, row = 2, col = 2) key.gf }, "nested.lattice" = , "nested.centroids" = { dx <- inner/2 dy <- dx/sqrt(3) hexC <- hexcoords(dx, dy, n = 1, sep = NULL) ## _____________x scaling_____________________________ numb <- cut(floor(legend/inner), breaks = c(-1, 0, 2,4)) ## Note: In old code ## top breaks=c(-1,0,2,4,8), numb<- 5 and size=1:9 if (is.na(numb)) numb <- 4 switch(numb, { warning("not enough space for legend") return(textGrob("")) }, size <- 5, size <- c(1, 5, 9), size <- c(1, 3, 5, 7, 9)) xmax <- length(size) radius <- sqrt(minarea + (maxarea - minarea) * (size - 1)/9) txt <- as.character(size) ##___________________y scaling_____________________ lab <- c("Ones", "Tens", "Hundreds", "Thousands", "10 Thousands", "100 Thousands", "Millions", "10 Millions", "100 Millions", "Billions") power <- floor(log10(maxcnt)) + 1 yinc <- 16 * dy ysize <- yinc * power xmid <- 0 x <- inner * (1:xmax - (1 + xmax)/2) + xmid n <- length(x) tx <- rep.int(hexC$x, n) ty <- rep.int(hexC$y, n) six <- rep.int(6:6, n) ## y <- rep.int(3 * dy - yinc, xmax) y <- rep.int(3 * dy - 0.75 * yinc, xmax) if (is.null(pen)) { pen <- 1:power +1 pen <- cbind(pen, pen +10) } if (is.null(border)) border <- TRUE key.layout <- grid.layout(nrow = 1, ncol = 1, heights = unit(ysize, "inches"), widths = unit(legend, "inches"), respect = TRUE) key.gf <- frameGrob(layout = key.layout, vp = vp) ## for debugging ## key.gf <- ## placeGrob(key.gf, rectGrob(gp = gpar(fill = "transparent"))) n6 <- rep.int(6, n) for(i in 1:power) { y <- y + yinc key.gf <- placeGrob(key.gf, polygonGrob(x = unit(legend / 2 + rep.int(hexC$x, n) + rep.int(x, n6), "inches"), y = unit(rep.int(hexC$y, n) + rep.int(y, n6), "inches"), id.lengths = n6, gp = gpar(col = pen[i, 1], fill = if (border) 1 else pen[i, 1])), row = 1, col = 1) key.gf <- placeGrob(key.gf, polygonGrob(x = legend / 2 + tx * rep.int(radius, six) + rep.int(x, six), y = ty * rep.int(radius, six) + rep.int(y, six), default.units = "inches", id=NULL, id.lengths=rep(6,n), gp = gpar(fill = pen[i,2], col = border)), row = 1, col = 1) key.gf <- placeGrob(key.gf, textGrob(txt, x = legend / 2 + x, y = y - 4.5 * dy, default.units = "inches", gp = gpar(cex = cex.labels)), row = 1, col = 1) key.gf <- placeGrob(key.gf, textGrob(lab[i], x = legend / 2 + xmid, y = y[1] + 4.5 * dy, default.units = "inches", gp = gpar(cex = 1.3 * cex.title)), row = 1, col = 1) } key.gf }) if (draw) { grid.draw(ans) invisible(ans) } else ans } hexbin/R/HO.R0000644000175100001440000001362111551510077012404 0ustar hornikusersheat.ob <- function(n,beg = 1,end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0, 0, 0), c(35, 0, 0), c(52, 0, 0), c(60, 0, 0), c(63, 1, 0), c(64, 2, 0), c(68, 5, 0), c(69, 6, 0), c(72, 8, 0), c(74,10, 0), c(77,12, 0), c(78,14, 0), c(81,16, 0), c(83,17, 0), c(85,19, 0), c(86,20, 0), c(89,22, 0), c(91,24, 0), c(92,25, 0), c(94,26, 0), c(95,28, 0), c(98,30, 0), c(100,31, 0), c(102,33, 0), c(103,34, 0), c(105,35, 0), c(106,36, 0), c(108,38, 0), c(109,39, 0), c(111,40, 0), c(112,42, 0), c(114,43, 0), c(115,44, 0), c(117,45, 0), c(119,47, 0), c(119,47, 0), c(120,48, 0), c(122,49, 0), c(123,51, 0), c(125,52, 0), c(125,52, 0), c(126,53, 0), c(128,54, 0), c(129,56, 0), c(129,56, 0), c(131,57, 0), c(132,58, 0), c(134,59, 0), c(134,59, 0), c(136,61, 0), c(137,62, 0), c(137,62, 0), c(139,63, 0), c(139,63, 0), c(140,65, 0), c(142,66, 0), c(142,66, 0), c(143,67, 0), c(143,67, 0), c(145,68, 0), c(145,68, 0), c(146,70, 0), c(146,70, 0), c(148,71, 0), c(148,71, 0), c(149,72, 0), c(149,72, 0), c(151,73, 0), c(151,73, 0), c(153,75, 0), c(153,75, 0), c(154,76, 0), c(154,76, 0), c(154,76, 0), c(156,77, 0), c(156,77, 0), c(157,79, 0), c(157,79, 0), c(159,80, 0), c(159,80, 0), c(159,80, 0), c(160,81, 0), c(160,81, 0), c(162,82, 0), c(162,82, 0), c(163,84, 0), c(163,84, 0), c(165,85, 0), c(165,85, 0), c(166,86, 0), c(166,86, 0), c(166,86, 0), c(168,87, 0), c(168,87, 0), c(170,89, 0), c(170,89, 0), c(171,90, 0), c(171,90, 0), c(173,91, 0), c(173,91, 0), c(174,93, 0), c(174,93, 0), c(176,94, 0), c(176,94, 0), c(177,95, 0), c(177,95, 0), c(179,96, 0), c(179,96, 0), c(180,98, 0), c(182,99, 0), c(182,99, 0), c(183,100, 0), c(183,100, 0), c(185,102, 0), c(185,102, 0), c(187,103, 0), c(187,103, 0), c(188,104, 0), c(188,104, 0), c(190,105, 0), c(191,107, 0), c(191,107, 0), c(193,108, 0), c(193,108, 0), c(194,109, 0), c(196,110, 0), c(196,110, 0), c(197,112, 0), c(197,112, 0), c(199,113, 0), c(200,114, 0), c(200,114, 0), c(202,116, 0), c(202,116, 0), c(204,117, 0), c(205,118, 0), c(205,118, 0), c(207,119, 0), c(208,121, 0), c(208,121, 0), c(210,122, 0), c(211,123, 0), c(211,123, 0), c(213,124, 0), c(214,126, 0), c(214,126, 0), c(216,127, 0), c(217,128, 0), c(217,128, 0), c(219,130, 0), c(221,131, 0), c(221,131, 0), c(222,132, 0), c(224,133, 0), c(224,133, 0), c(225,135, 0), c(227,136, 0), c(227,136, 0), c(228,137, 0), c(230,138, 0), c(230,138, 0), c(231,140, 0), c(233,141, 0), c(233,141, 0), c(234,142, 0), c(236,144, 0), c(236,144, 0), c(238,145, 0), c(239,146, 0), c(241,147, 0), c(241,147, 0), c(242,149, 0), c(244,150, 0), c(244,150, 0), c(245,151, 0), c(247,153, 0), c(247,153, 0), c(248,154, 0), c(250,155, 0), c(251,156, 0), c(251,156, 0), c(253,158, 0), c(255,159, 0), c(255,159, 0), c(255,160, 0), c(255,161, 0), c(255,163, 0), c(255,163, 0), c(255,164, 0), c(255,165, 0), c(255,167, 0), c(255,167, 0), c(255,168, 0), c(255,169, 0), c(255,169, 0), c(255,170, 0), c(255,172, 0), c(255,173, 0), c(255,173, 0), c(255,174, 0), c(255,175, 0), c(255,177, 0), c(255,178, 0), c(255,179, 0), c(255,181, 0), c(255,181, 0), c(255,182, 0), c(255,183, 0), c(255,184, 0), c(255,187, 7), c(255,188,10), c(255,189,14), c(255,191,18), c(255,192,21), c(255,193,25), c(255,195,29), c(255,197,36), c(255,198,40), c(255,200,43), c(255,202,51), c(255,204,54), c(255,206,61), c(255,207,65), c(255,210,72), c(255,211,76), c(255,214,83), c(255,216,91), c(255,219,98), c(255,221,105), c(255,223,109), c(255,225,116), c(255,228,123), c(255,232,134), c(255,234,142), c(255,237,149), c(255,239,156), c(255,240,160), c(255,243,167), c(255,246,174), c(255,248,182), c(255,249,185), c(255,252,193), c(255,253,196), c(255,255,204), c(255,255,207), c(255,255,211), c(255,255,218), c(255,255,222), c(255,255,225), c(255,255,229), c(255,255,233), c(255,255,236), c(255,255,240), c(255,255,244), c(255,255,247), c(255,255,255))[ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/BTC.R0000644000175100001440000001367111551510077012513 0ustar hornikusersBTC <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,40), c(0,4,56), c(0,9,61), c(0,12,64), c(0,14,66), c(0,17,69), c(0,20,73), c(0,22,74), c(0,25,78), c(0,27,79), c(0,30,83), c(0,31,85), c(0,33,86), c(0,36,90), c(0,38,91), c(0,39,93), c(0,41,95), c(0,43,96), c(0,46,100), c(0,47,102), c(0,49,103), c(0,51,105), c(0,52,107), c(0,54,108), c(0,55,110), c(0,57,112), c(0,57,112), c(0,58,113), c(0,60,115), c(0,62,117), c(0,63,119), c(0,65,120), c(0,66,122), c(0,68,124), c(0,70,125), c(0,71,127), c(0,73,129), c(0,73,129), c(0,74,130), c(0,76,132), c(0,78,134), c(0,79,136), c(0,81,137), c(0,82,139), c(0,84,141), c(0,86,142), c(0,87,144), c(0,89,146), c(0,90,147), c(0,92,149), c(0,94,151), c(0,94,151), c(0,95,153), c(0,97,154), c(0,98,156), c(0,100,158), c(0,102,159), c(0,103,161), c(0,105,163), c(0,106,164), c(0,108,166), c(0,109,168), c(0,111,170), c(0,113,171), c(0,114,173), c(0,116,175), c(0,117,176), c(0,119,178), c(0,121,180), c(0,121,180), c(0,122,181), c(0,124,183), c(0,125,185), c(0,127,187), c(0,129,188), c(0,130,190), c(0,132,192), c(0,133,193), c(0,135,195), c(0,137,197), c(0,138,198), c(0,140,200), c(0,141,202), c(0,143,204), c(0,143,204), c(0,145,205), c(0,146,207), c(0,148,209), c(0,149,210), c(0,151,212), c(0,153,214), c(0,154,215), c(0,156,217), c(0,157,219), c(0,159,221), c(0,160,222), c(0,160,222), c(0,162,224), c(0,164,226), c(0,165,227), c(0,167,229), c(0,168,231), c(0,170,232), c(0,172,234), c(0,173,236), c(0,175,238), c(0,175,238), c(0,176,239), c(0,178,241), c(0,180,243), c(0,181,244), c(0,183,246), c(2,184,248), c(4,186,249), c(4,186,249), c(4,186,249), c(6,188,251), c(6,188,251), c(9,189,253), c(9,189,253), c( 11,191,255), c( 11,191,255), c( 13,192,255), c( 13,192,255), c( 13,192,255), c( 16,194,255), c( 18,196,255), c( 20,197,255), c( 20,197,255), c( 23,199,255), c( 25,200,255), c( 27,202,255), c( 30,204,255), c( 32,205,255), c( 34,207,255), c( 37,208,255), c( 37,208,255), c( 39,210,255), c( 41,211,255), c( 44,213,255), c( 46,215,255), c( 48,216,255), c( 51,218,255), c( 53,219,255), c( 53,219,255), c( 55,221,255), c( 57,223,255), c( 60,224,255), c( 62,226,255), c( 64,227,255), c( 67,229,255), c( 67,229,255), c( 69,231,255), c( 71,232,255), c( 74,234,255), c( 76,235,255), c( 78,237,255), c( 81,239,255), c( 81,239,255), c( 83,240,255), c( 85,242,255), c( 88,243,255), c( 90,245,255), c( 92,247,255), c( 95,248,255), c( 95,248,255), c( 97,250,255), c( 99,251,255), c(102,253,255), c(104,255,255), c(106,255,255), c(106,255,255), c(108,255,255), c(111,255,255), c(113,255,255), c(115,255,255), c(115,255,255), c(118,255,255), c(120,255,255), c(122,255,255), c(122,255,255), c(125,255,255), c(127,255,255), c(129,255,255), c(129,255,255), c(132,255,255), c(134,255,255), c(136,255,255), c(136,255,255), c(139,255,255), c(141,255,255), c(143,255,255), c(143,255,255), c(146,255,255), c(148,255,255), c(150,255,255), c(150,255,255), c(153,255,255), c(155,255,255), c(155,255,255), c(157,255,255), c(159,255,255), c(159,255,255), c(162,255,255), c(164,255,255), c(164,255,255), c(166,255,255), c(169,255,255), c(171,255,255), c(171,255,255), c(173,255,255), c(176,255,255), c(176,255,255), c(178,255,255), c(180,255,255), c(180,255,255), c(183,255,255), c(185,255,255), c(185,255,255), c(187,255,255), c(190,255,255), c(190,255,255), c(192,255,255), c(194,255,255), c(197,255,255), c(197,255,255), c(199,255,255), c(201,255,255), c(204,255,255), c(204,255,255), c(206,255,255), c(208,255,255), c(210,255,255), c(210,255,255), c(213,255,255), c(215,255,255), c(217,255,255), c(217,255,255), c(220,255,255), c(222,255,255), c(224,255,255), c(227,255,255), c(229,255,255), c(229,255,255), c(231,255,255), c(234,255,255), c(236,255,255), c(238,255,255), c(241,255,255), c(243,255,255), c(243,255,255), c(245,255,255), c(248,255,255), c(250,255,255), c(255,255,255))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hbox.R0000644000175100001440000000517011551510077013036 0ustar hornikusershboxplot <- function(bin, xbnds = NULL, ybnds = NULL, density, border = c(0,grey(.7)), pen = c(2, 3), unzoom = 1.1, clip="off", reshape = FALSE, xlab = NULL, ylab = NULL, main = "") { ##_______________ Collect computing constants______________ if(!is(bin,"hexbin")) stop("first argument must be a hexbin object") h.xy <- hcell2xy(bin,check.erosion=TRUE) ##___zoom in scaling with expanding to avoid hexagons outside plot frame___ if(is(bin,"erodebin")) { h.xy$x <- h.xy$x h.xy$y <- h.xy$y nxbnds <- if(is.null(xbnds)) range(h.xy$x) else xbnds nybnds <- if(is.null(ybnds)) range(h.xy$y) else ybnds ratiox <- diff(nxbnds)/diff(bin@xbnds) ratioy <- diff(nybnds)/diff(bin@ybnds) ratio <- max(ratioy, ratiox) nxbnds <- mean(nxbnds) + c(-1,1)*(unzoom * ratio * diff(bin@xbnds))/2 nybnds <- mean(nybnds) + c(-1,1)*(unzoom * ratio * diff(bin@ybnds))/2 } else { nxbnds <- if(is.null(xbnds)) bin@xbnds else xbnds nybnds <- if(is.null(ybnds)) bin@ybnds else ybnds } margins <- unit(0.1 + c(5,4,4,3),"lines") plot.vp <- hexViewport(bin, xbnds = nxbnds, ybnds = nybnds, mar=margins, newpage = TRUE) pushHexport(plot.vp) grid.rect() grid.xaxis() grid.yaxis() ## xlab, ylab, main : if(is.null(xlab)) xlab <- bin@xlab if(is.null(ylab)) ylab <- bin@ylab if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp= gpar(fontsize= 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp= gpar(fontsize= 16), rot = 90) if(nchar(main) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(clip=="on") { popViewport() pushHexport(plot.vp, clip="on") } cnt <- if(is(bin,"erodebin")) bin@count[bin@eroded] else bin@count xbins <- bin@xbins shape <- bin@shape xnew <- h.xy$x ynew <- h.xy$y ##__________________ Construct a hexagon___________________ dx <- (0.5 * diff(bin@xbnds))/xbins dy <- (0.5 * diff(bin@ybnds))/(xbins * shape * sqrt(3)) hexC <- hexcoords(dx, dy, sep = NULL) ##_______________ Full Cell Plotting_____________________ hexpolygon(xnew, ynew, hexC, density = density, fill = pen[2], border = border[2]) ##______________Plotting median___________________________ if(!is(bin,"erodebin")) { ## No warning here, allow non-erode above! warning("No erode component") } else { med <- which.max(bin@erode) xnew <- xnew[med] ynew <- ynew[med] hexpolygon(xnew, ynew, hexC, density = density, fill = pen[1], border = border[1]) } popViewport() invisible(plot.vp) }# hboxplot() hexbin/R/MAG.R0000644000175100001440000001437211551510077012506 0ustar hornikusersmagent <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0, 0, 0), c( 40, 0, 0), c( 56, 0, 4), c( 61, 0, 9), c( 64, 0, 12), c( 66, 0, 14), c( 69, 0, 17), c( 73, 0, 20), c( 74, 0, 22), c( 78, 0, 25), c( 79, 0, 27), c( 83, 0, 30), c( 85, 0, 31), c( 86, 0, 33), c( 90, 0, 36), c( 91, 0, 38), c( 93, 0, 39), c( 95, 0, 41), c( 96, 0, 43), c(100, 0, 46), c(102, 0, 47), c(103, 0, 49), c(105, 0, 51), c(107, 0, 52), c(108, 0, 54), c(110, 0, 55), c(112, 0, 57), c(112, 0, 57), c(113, 0, 58), c(115, 0, 60), c(117, 0, 62), c(119, 0, 63), c(120, 0, 65), c(122, 0, 66), c(124, 0, 68), c(125, 0, 70), c(127, 0, 71), c(129, 0, 73), c(129, 0, 73), c(130, 0, 74), c(132, 0, 76), c(134, 0, 78), c(136, 0, 79), c(137, 0, 81), c(139, 0, 82), c(141, 0, 84), c(142, 0, 86), c(144, 0, 87), c(146, 0, 89), c(147, 0, 90), c(149, 0, 92), c(151, 0, 94), c(151, 0, 94), c(153, 0, 95), c(154, 0, 97), c(156, 0, 98), c(158, 0,100), c(159, 0,102), c(161, 0,103), c(163, 0,105), c(164, 0,106), c(166, 0,108), c(168, 0,109), c(170, 0,111), c(171, 0,113), c(173, 0,114), c(175, 0,116), c(176, 0,117), c(178, 0,119), c(180, 0,121), c(180, 0,121), c(181, 0,122), c(183, 0,124), c(185, 0,125), c(187, 0,127), c(188, 0,129), c(190, 0,130), c(192, 0,132), c(193, 0,133), c(195, 0,135), c(197, 0,137), c(198, 0,138), c(200, 0,140), c(202, 0,141), c(204, 0,143), c(204, 0,143), c(205, 0,145), c(207, 0,146), c(209, 0,148), c(210, 0,149), c(212, 0,151), c(214, 0,153), c(215, 0,154), c(217, 0,156), c(219, 0,157), c(221, 0,159), c(222, 0,160), c(222, 0,160), c(224, 0,162), c(226, 0,164), c(227, 0,165), c(229, 0,167), c(231, 0,168), c(232, 0,170), c(234, 0,172), c(236, 0,173), c(238, 0,175), c(238, 0,175), c(239, 0,176), c(241, 0,178), c(243, 0,180), c(244, 0,181), c(246, 0,183), c(248, 2,184), c(249, 4,186), c(249, 4,186), c(249, 4,186), c(251, 6,188), c(251, 6,188), c(253, 9,189), c(253, 9,189), c(255, 11,191), c(255, 11,191), c(255, 13,192), c(255, 13,192), c(255, 13,192), c(255, 16,194), c(255, 18,196), c(255, 20,197), c(255, 20,197), c(255, 23,199), c(255, 25,200), c(255, 27,202), c(255, 30,204), c(255, 32,205), c(255, 34,207), c(255, 37,208), c(255, 37,208), c(255, 39,210), c(255, 41,211), c(255, 44,213), c(255, 46,215), c(255, 48,216), c(255, 51,218), c(255, 53,219), c(255, 53,219), c(255, 55,221), c(255, 57,223), c(255, 60,224), c(255, 62,226), c(255, 64,227), c(255, 67,229), c(255, 67,229), c(255, 69,231), c(255, 71,232), c(255, 74,234), c(255, 76,235), c(255, 78,237), c(255, 81,239), c(255, 81,239), c(255, 83,240), c(255, 85,242), c(255, 88,243), c(255, 90,245), c(255, 92,247), c(255, 95,248), c(255, 95,248), c(255, 97,250), c(255, 99,251), c(255,102,253), c(255,104,255), c(255,106,255), c(255,106,255), c(255,108,255), c(255,111,255), c(255,113,255), c(255,115,255), c(255,115,255), c(255,118,255), c(255,120,255), c(255,122,255), c(255,122,255), c(255,125,255), c(255,127,255), c(255,129,255), c(255,129,255), c(255,132,255), c(255,134,255), c(255,136,255), c(255,136,255), c(255,139,255), c(255,141,255), c(255,143,255), c(255,143,255), c(255,146,255), c(255,148,255), c(255,150,255), c(255,150,255), c(255,153,255), c(255,155,255), c(255,155,255), c(255,157,255), c(255,159,255), c(255,159,255), c(255,162,255), c(255,164,255), c(255,164,255), c(255,166,255), c(255,169,255), c(255,171,255), c(255,171,255), c(255,173,255), c(255,176,255), c(255,176,255), c(255,178,255), c(255,180,255), c(255,180,255), c(255,183,255), c(255,185,255), c(255,185,255), c(255,187,255), c(255,190,255), c(255,190,255), c(255,192,255), c(255,194,255), c(255,197,255), c(255,197,255), c(255,199,255), c(255,201,255), c(255,204,255), c(255,204,255), c(255,206,255), c(255,208,255), c(255,210,255), c(255,210,255), c(255,213,255), c(255,215,255), c(255,217,255), c(255,217,255), c(255,220,255), c(255,222,255), c(255,224,255), c(255,227,255), c(255,229,255), c(255,229,255), c(255,231,255), c(255,234,255), c(255,236,255), c(255,238,255), c(255,241,255), c(255,243,255), c(255,243,255), c(255,245,255), c(255,248,255), c(255,250,255), c(255,255,255)) [ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hdiffplot.R0000644000175100001440000003121512372064472014061 0ustar hornikusers ### FIXME: Need to check for bin erosion ### or fix hcell2xy so that it checks for bin erosion. ### --- Fixed hcell2xy, probably should do the same to other accessor functions ### NL get.xrange <- function(xy.lst, xbnds) { range(unlist(lapply(xy.lst, function(xy, bnd) xy$x[(xy$x < max(bnd)) & (xy$x > min(bnd))], xbnds))) } get.yrange <- function(xy.lst, ybnds) { range(unlist(lapply(xy.lst, function(xy, bnd) xy$y[(xy$y < max(bnd)) & (xy$y > min(bnd))], ybnds))) } make.bnds <- function(binlst, xy.lst, xbnds = NULL, ybnds = NULL) { if(inherits(binlst,"hexbinList")) binlst <- binlst@hbins if(is.null(xbnds)) xbnds <- binlst[[1]]@xbnds if(is.null(ybnds)) ybnds <- binlst[[1]]@ybnds nxbnds <- get.xrange(xy.lst, xbnds) nybnds <- get.yrange(xy.lst, ybnds) list(xbnds = xbnds, ybnds = ybnds, nxbnds = nxbnds, nybnds = nybnds) } all.intersect <- function(binlist) { ## This will not work if all the grids are not the same ## Will have to rethink this if we move to non-aligned ## hexagon bins. NL if(inherits(binlist,"hexbinList")) binlist <- binlist@hbins ans <- matrix(FALSE, nrow = binlist[[1]]@dimen[1]*binlist[[1]]@dimen[2], ncol = length(binlist)) for(i in 1:length(binlist)) { if(is(binlist[[i]], "erodebin")) ans[binlist[[i]]@cell[binlist[[i]]@eroded], i] <- TRUE else ans[binlist[[i]]@cell, i] <- TRUE } ans } ## colordist <- function() { ## } ## MM: FIXME : `` get(where) '' is a kludge! # EJP: outcomment, seems obsolete? #mixcolors <- function (alpha, color1, where = class(color1)) #{ # alpha <- as.numeric(alpha) # c1 <- coords(as(color1, where)) # na <- length(alpha) # n1 <- nrow(c1) # if(na == 1) # alpha <- rep(alpha, n1) # stopifnot(sum(alpha) == 1) # get(where)(t(apply(c1, 2, function(cols, alpha) alpha%*%cols, alpha))) # #} mixcolors2 <- function (colors, alpha, where="hsv") { # colors: an n x 3 matrix of colors # alpha: an n x 1 vector of color mixing coefficents # sum(alpha)==1 should be a restriction? # where: the color space to mix in (not implemented yet) # The reurn value is a single hex color forming the mixture # This function is purely linear mixing, nolinear mixing # would be quite interesting since the colorspaces are not really # linear, ie mixing alonga manifold in LUV space. alpha <- as.numeric(alpha) na <- length(alpha) n1 <- nrow(colors) if (n1 < 2) { warning("need more than two colors to mix") colors } if(na == 1) alpha <- rep(alpha, n1) stopifnot(abs(sum(alpha)-1) <= 0.01) #colors <- convertColor(colors,from="sRGB",to="Lab",scale.in=1) mix <- t(apply(colors, 2, function(cols, alpha) alpha%*%cols, alpha)) #convertColor(mix,from="hsv",to="hex",scale.out=1,clip=TRUE) hsv(mix[1],mix[2],mix[3]) } hdiffplot <- function(bin1, bin2 = NULL, xbnds = NULL, ybnds = NULL, focus = NULL, col.control = list(medhex = "white", med.bord = "black", focus = NULL, focus.border = NULL, back.col = "grey"), arrows = TRUE, size = unit(0.1, "inches"), lwd = 2, eps = 1e-6, unzoom = 1.08, clip ="off", xlab = "", ylab = "", main = deparse(mycall), ...) { ## Arguments: ## bin1 : hexagon bin object or a list of bin objects ## bin2 : hexagon bin object or NULL ## bin objects must have the same plotting bounds and shape ## border : plot the border of the hexagon, use TRUE for ## hexagon graph paper ## Having all the same parameters ensures that all hexbin ## objects have the same hexagon grid, and there will be no ## problems intersecting them. When we have a suitable solution to ## the hexagon interpolation/intersection problem this will be relaxed. fixx <- xbnds fixy <- ybnds if(!inherits(bin1,"hexbinList")){ if(is.null(bin2) & is.list(bin1)) { bin1 <- as(bin1,"hexbinList") } else if(is.null(bin2) & (!is.list(bin1))) stop(" need at least 2 hex bin objects, or a hexbinList") else { if(bin1@shape != bin2@shape) stop("bin objects must have same shape parameter") if(all(bin1@xbnds == bin2@xbnds) & all(bin1@ybnds == bin2@ybnds)) equal.bounds <- TRUE else stop("Bin objects need the same xbnds and ybnds") if(bin1@xbins != bin2@xbins) stop("Bin objects need the same number of bins") nhb <- 2 ## Need to make a binlist class, then can do as(bin1, bin2, "binlist") ## or something similar (NL) bin1 <- list(bin1 = bin1, bin2 = bin2) bin1 <- as(bin1,"hexbinList") } } mycall <- sys.call() if(length(mycall) >= 4) { mycall[4] <- as.call(quote(.....())) if(length(mycall) > 4) mycall <- mycall[1:4] } if(is.null(focus)) focus <- 1:bin1@n ##_______________ Collect computing constants______________ tmph.xy <- lapply(bin1@hbins, hcell2xy, check.erosion = TRUE) ## Check for erode bins eroded <- unlist(lapply(bin1@hbins, is, "erodebin")) shape <- bin1@Shape xbins <- bin1@Xbins bnds <- make.bnds(bin1@hbins, tmph.xy, xbnds = fixx, ybnds = fixy) ratiox <- diff(bnds$nxbnds)/diff(bnds$xbnds) ratioy <- diff(bnds$nybnds)/diff(bnds$ybnds) ratio <- max(ratioy, ratiox) nxbnds <- mean(bnds$nxbnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$xbnds))/2 nybnds <- mean(bnds$nybnds) + c(-1, 1)*(unzoom * ratio * diff(bnds$ybnds))/2 ##__________________ Construct plot region___________________ hvp <- hexViewport(bin1@hbins[[1]], xbnds = nxbnds, ybnds = nybnds, newpage = TRUE) pushHexport(hvp) grid.rect() grid.xaxis() grid.yaxis() if(nchar(xlab) > 0) grid.text(xlab, y = unit(-2, "lines"), gp = gpar(fontsize = 16)) if(nchar(ylab) > 0) grid.text(ylab, x = unit(-2, "lines"), gp = gpar(fontsize = 16), rot = 90) if(sum(nchar(main)) > 0) grid.text(main, y = unit(1, "npc") + unit(1.5, "lines"), gp = gpar(fontsize = 18)) if(clip=='on'){ popViewport() pushHexport(hvp,clip="on") } ##__________________ Construct hexagon___________________ dx <- (0.5 * diff(bin1@Xbnds))/xbins dy <- (0.5 * diff(bin1@Ybnds))/(xbins * shape * sqrt(3)) hexC <- hexcoords(dx = dx, dy = dy) ##__________________ Set up intersections and colors___________________ if(length(focus) < bin1@n) { bin1@hbins <- c(bin1@hbins[focus], bin1@hbins[-focus]) bin1@Bnames <- c(bin1@Bnames[focus], bin1@Bnames[-focus]) } cell.stat <- all.intersect(bin1@hbins) cell.stat.n <- apply(cell.stat, 1, sum) i.depth <- max(cell.stat.n) ### I will do this as a recursive function once I get ### The colors worked out! In fact for more than three ### bin objects there is no other way to do this but recursively!!! ### NL. -- Well this solution is like recursion :) diff.cols <- vector(mode = "list", length = i.depth) levcells <- which(cell.stat.n == 1) whichbin <- apply(cell.stat[levcells, ], 1, which) ## Set all the focal colors for the unique bin cells ## if not specified make them equally spaced on the color wheel ## with high saturation and set the background bins to gray nfcol <- length(focus) nhb <- bin1@n nbcol <- nhb-nfcol fills <- if(is.null(col.control$focus)) { if(nbcol > 0) matrix(c(seq(0, 360, length = nfcol+1)[1:nfcol]/360, rep(0, nbcol), rep(1, nfcol), rep(0, nbcol),rep(1, nfcol), rep(.9, nbcol)), ncol = 3) ## V = c(rep(1, nfcol), seq(.9, .1, length=nbcol)) else #matrix(c(seq(0, 360, length = nhb+1), s=1, v=1)[1:nfcol] matrix(c(seq(0, 360, length = nhb+1)/360, rep(1,nhb+1), rep(1,nhb+1)), ncol = 3)[1:nhb,] } else { foc.col <- t(rgb2hsv(col2rgb(col.control$focus))) if(nbcol > 0) { bcol <- matrix(c(rep(0, 2*nbcol), rep(.9, nbcol)), ncol = 3) rbind(foc.col, bcol) } else foc.col } colnames(fills) <- c("h","s","v") diff.cols[[1]] <- list(fill = fills, border = gray(.8)) ##_______________ Full Cell Plotting for Unique Bin1 Cells_________________ if(length(levcells) > 0) { for(i in unique(whichbin)) { pcells <- if(eroded[i]) bin1@hbins[[i]]@cell[bin1@hbins[[i]]@eroded] else bin1@hbins[[i]]@cell pcells <- which(pcells %in% levcells[whichbin == i]) pfill <- diff.cols[[1]]$fill[i,] pfill <- hsv(pfill[1],pfill[2],pfill[3]) hexpolygon(x = tmph.xy[[i]]$x[pcells], y = tmph.xy[[i]]$y[pcells], hexC, border = diff.cols[[1]]$border , fill = pfill) } } ## Now do the intersections. All intersections are convex ## combinations of the colors of the overlapping unique bins in ## the CIEluv colorspace. so if the binlist is of length 2 and ## the focal hbins are "blue" and "yellow" respectively the ## intersection would be green. First I need to get this to work ## and then I can think about how to override this with an option ## in color.control. -NL if(i.depth > 1) { for(dl in 2:(i.depth)) { levcells <- which(cell.stat.n == dl) if(length(levcells) == 0) next whichbin <- apply(cell.stat[levcells, ], 1, function(x) paste(which(x), sep = "", collapse = ":")) inter.nm <- unique(whichbin) #fills <- matrix(0, length(inter.nm), 3) fills <- rep(hsv(1), length(inter.nm)) i <- 1 for(bn in inter.nm) { who <- as.integer(unlist(strsplit(bn, ":"))) fills[i] <- mixcolors2(diff.cols[[1]]$fill[who,], 1/length(who),where = "LUV") i <- i+1 } #fills <- LUV(fills) diff.cols[[dl]] <- list(fill = fills, border = gray((i.depth-dl)/i.depth)) ##____Full Cell Plotting for Intersecting Cells at Intersection Depth i____ i <- 1 for(ints in inter.nm) { bin.i <- as.integer(unlist(strsplit(ints, ":"))[1]) pcells <- if(eroded[bin.i]) bin1@hbins[[bin.i]]@cell[bin1@hbins[[bin.i]]@eroded] else bin1@hbins[[bin.i]]@cell pcells <- which(pcells %in% levcells[whichbin == ints]) hexpolygon(x = tmph.xy[[bin.i]]$x[pcells], y = tmph.xy[[bin.i]]$y[pcells], hexC, border = diff.cols[[dl]]$border , fill = diff.cols[[dl]]$fill[i] ) i <- i+1 } } } ##_____________________________Plot Median Cells___________________________ ## With all these colors floating around I think it would be worth ## porting the 3d hexagon stuff to grid. Then it would be easier ## to distinguish the medians because they would stand out like ## little volcanoes :) NL if(any(eroded)) { hmeds <- matrix(unlist(lapply(bin1@hbins[eroded], function(x) unlist(getHMedian(x)))), ncol = 2, byrow = TRUE) hexpolygon(x = hmeds[, 1], y = hmeds[, 2], hexC, border = col.control$med.b, fill = col.control$medhex) if(arrows) { for(i in focus) { for(j in focus[focus < i]) { if(abs(hmeds[i, 1] - hmeds[j, 1]) + abs(hmeds[i, 2] - hmeds[j, 2]) > eps) grid.lines(c(hmeds[i, 1],hmeds[j, 1]), c(hmeds[i, 2], hmeds[j, 2]), default.units = "native", arrow=arrow(length=size)) #grid.arrows(c(hmeds[i, 1], hmeds[j, 1]), # c(hmeds[i, 2], hmeds[j, 2]), # default.units = "native", # length = size, gp = gpar(lwd = lwd)) } } } } ##________________Clean Up_______________________________________________ popViewport() invisible(hvp) } ## hdiffplot() hexbin/R/LOCS.R0000644000175100001440000001306311551510077012636 0ustar hornikusersLinOCS <- function(n,beg = 1,end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,0), c(0,0,0), c(1,0,0), c(2,0,0), c(2,0,0), c(3,0,0), c(3,0,0), c(4,0,0), c(5,0,0), c(5,0,0), c(6,0,0), c(7,0,0), c(7,0,0), c(8,0,0), c(9,0,0), c(9,0,0), c(10,0,0), c(11,0,0), c(12,0,0), c(13,0,0), c(14,0,0), c(15,0,0), c(16,0,0), c(17,0,0), c(18,0,0), c(19,0,0), c(20,0,0), c(21,0,0), c(22,0,0), c(23,0,0), c(25,0,0), c(26,0,0), c(27,0,0), c(28,0,0), c(30,0,0), c(31,0,0), c(33,0,0), c(34,0,0), c(35,0,0), c(37,0,0), c(39,0,0), c(40,0,0), c(43,0,0), c(45,0,0), c(46,0,0), c(49,0,0), c(51,0,0), c(53,0,0), c(54,0,0), c(56,0,0), c(58,0,0), c(60,0,0), c(62,0,0), c(64,0,0), c(67,0,0), c(69,0,0), c(71,0,0), c(74,0,0), c(76,0,0), c(80,0,0), c(81,0,0), c(84,0,0), c(86,0,0), c(89,0,0), c(92,0,0), c(94,0,0), c(97,0,0), c(100,0,0), c(103,0,0), c(106,0,0), c(109,0,0), c(112,0,0), c(115,0,0), c(117,0,0), c(122,0,0), c(126,0,0), c(128,0,0), c(131,0,0), c(135,0,0), c(135,0,0), c(135,1,0), c(135,2,0), c(135,3,0), c(135,4,0), c(135,6,0), c(135,6,0), c(135,8,0), c(135,9,0), c(135,10,0), c(135,11,0), c(135,13,0), c(135,13,0), c(135,15,0), c(135,17,0), c(135,17,0), c(135,19,0), c(135,21,0), c(135,22,0), c(135,23,0), c(135,25,0), c(135,26,0), c(135,27,0), c(135,29,0), c(135,31,0), c(135,32,0), c(135,33,0), c(135,35,0), c(135,36,0), c(135,38,0), c(135,40,0), c(135,42,0), c(135,44,0), c(135,46,0), c(135,47,0), c(135,49,0), c(135,51,0), c(135,52,0), c(135,54,0), c(135,56,0), c(135,57,0), c(135,59,0), c(135,62,0), c(135,63,0), c(135,65,0), c(135,67,0), c(135,69,0), c(135,72,0), c(135,73,0), c(135,76,0), c(135,78,0), c(135,80,0), c(135,82,0), c(135,84,0), c(135,87,0), c(135,88,0), c(135,90,0), c(135,93,0), c(135,95,0), c(135,98,0), c(135,101,0), c(135,103,0), c(135,106,0), c(135,107,0), c(135,110,0), c(135,113,0), c(135,115,0), c(135,118,0), c(135,121,0), c(135,124,0), c(135,127,0), c(135,129,0), c(135,133,0), c(135,135,0), c(135,138,0), c(135,141,0), c(135,144,0), c(135,148,0), c(135,150,0), c(135,155,0), c(135,157,0), c(135,160,0), c(135,163,0), c(135,166,0), c(135,170,0), c(135,174,0), c(135,177,0), c(135,180,0), c(135,184,0), c(135,188,0), c(135,192,0), c(135,195,0), c(135,200,0), c(135,203,0), c(135,205,0), c(135,210,0), c(135,214,0), c(135,218,0), c(135,222,0), c(135,226,0), c(135,231,0), c(135,236,0), c(135,239,0), c(135,244,0), c(135,249,0), c(135,254,0), c(135,255,1), c(135,255,5), c(135,255,10), c(135,255,15), c(135,255,20), c(135,255,23), c(135,255,28), c(135,255,33), c(135,255,38), c(135,255,43), c(135,255,45), c(135,255,49), c(135,255,54), c(135,255,59), c(135,255,65), c(135,255,70), c(135,255,74), c(135,255,80), c(135,255,84), c(135,255,90), c(135,255,95), c(135,255,98), c(135,255,104), c(135,255,110), c(135,255,116), c(135,255,120), c(135,255,125), c(135,255,131), c(135,255,137), c(135,255,144), c(135,255,149), c(135,255,154), c(135,255,158), c(135,255,165), c(135,255,172), c(135,255,179), c(135,255,186), c(135,255,191), c(135,255,198), c(135,255,203), c(135,255,211), c(135,255,216), c(135,255,224), c(135,255,232), c(135,255,240), c(135,255,248), c(135,255,254), c(135,255,255), c(140,255,255), c(146,255,255), c(153,255,255), c(156,255,255), c(161,255,255), c(168,255,255), c(172,255,255), c(177,255,255), c(182,255,255), c(189,255,255), c(192,255,255), c(199,255,255), c(204,255,255), c(210,255,255), c(215,255,255), c(220,255,255), c(225,255,255), c(232,255,255), c(236,255,255), c(240,255,255), c(248,255,255), c(255,255,255))[ round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexbinList.R0000644000175100001440000000627011551510077014211 0ustar hornikusershexList <- function(x,y=NULL,given=NULL,xbins=30,shape=1, xbnds = NULL, ybnds = NULL, xlab = NULL, ylab = NULL) { xl <- if (!missing(x)) deparse(substitute(x)) yl <- if (!missing(y)) deparse(substitute(y)) xy <- xy.coords(x, y, xl, yl) if(length(given)!=length(xy$x) | is.null(given)) stop("Given is is different length from x and y") if(is.factor(given)) given <- as.character(given) clss <- unique(given) if(is.null(xbnds)) xbnds <- range(xy$x) if(is.null(ybnds)) ybnds <- range(xy$y) hbins <- vector(mode = "list",length=length(clss)) i <- 1 for(g in clss){ hbins[[i]] <- hexbin(xy$x[given==g],xy$y[given==g], xbins=xbins,shape=shape,xbnds=xbnds,ybnds=ybnds) i <- i+1 } mx <- max(unlist(lapply(hbins,function(h)max(h@count)))) mn <- min(unlist(lapply(hbins,function(h)min(h@count)))) hl <- new("hexbinList",n=length(hbins),hbins=hbins, Xbnds=xbnds, Ybnds=ybnds, Xbins=integer(xbins), Shape=shape, Bnames=clss, CntBnds=c(mn,mx)) hl } setClass("hexbinList", representation(n="integer", hbins="vector", Xbnds="numeric", Ybnds="numeric", Xbins="numeric", Shape="numeric", Bnames="character", CntBnds="numeric") ) bnds.check <- function(binlst, xb = TRUE, yb = TRUE) { xb <- if(xb) { b <- binlst[[1]]@xbnds all(unlist(lapply(binlst, function(x, bnd) all(x@xbnds == bnd), b))) } else TRUE yb <- if(yb) { b <- binlst[[1]]@ybnds all(unlist(lapply(binlst, function(y, bnd) all(y@ybnds == bnd), b))) } else TRUE xb & yb } xbins.check <- function(binlst) { xb <- binlst[[1]]@xbins all(unlist(lapply(binlst, function(y, xbin)all(y@xbins == xbin), xb))) } shape.check <- function(binlst) { xs <- binlst[[1]]@shape all(unlist(lapply(binlst, function(y, xsh)all(y@shape == xsh), xs))) } list2hexList <- function(binlst) { if(length(binlst) < 2) stop(" need at least 2 hex bin objects") if(!all(unlist(lapply(binlst, is, "hexbin")))) stop("All Elements of list must be hexbin objects") if(!bnds.check(binlst)) stop("All bin objects in list need the same xbnds and ybnds") if(!xbins.check(binlst)) stop("All bin objects in list need the same number of bins") if(!shape.check(binlst)) stop("All bin objects in list need the same shape parameter") mx <- max(unlist(lapply(binlst,function(h)max(h@count)))) mn <- min(unlist(lapply(binlst,function(h)min(h@count)))) xbins <- binlst[[1]]@xbins xbnds <- binlst[[1]]@xbnds ybnds <- binlst[[1]]@ybnds shape <- binlst[[1]]@shape hl <- new("hexbinList",n=length(binlst),hbins=binlst, Xbnds=xbnds, Ybnds=ybnds, Xbins=xbins, Shape=shape, Bnames=names(binlst), CntBnds=c(mn,mx)) hl } setAs("list","hexbinList",function(from)list2hexList(from)) #setMethod("[", "hexbinList", function(hbl,i,...) #{ # if( length(list(...)) > 0 ) # stop("extra subscripts cannot be handled") # if(missing(i)) hbl # hbl@hbins[i] #}) ##setMethod("[[", "hexbinList", function(hbl) ##{ ##}) hexbin/R/BTY.R0000644000175100001440000001420611551510077012534 0ustar hornikusersBTY <- function(n, beg = 1, end = 256) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(7,7,254), c(23,23,252), c(30,30,250), c(36,36,248), c(40,40,247), c(44,44,245), c(47,47,243), c(50,50,242), c(52,52,240), c(55,55,239), c(57,57,238), c(59,59,236), c(61,61,235), c(63,63,234), c(65,65,233), c(66,66,231), c(68,68,230), c(69,69,229), c(71,71,228), c(72,72,227), c(74,74,226), c(75,75,225), c(76,76,225), c(78,78,224), c(79,79,223), c(80,80,222), c(81,81,221), c(82,82,221), c(84,84,220), c(85,85,219), c(86,86,218), c(87,87,218), c(88,88,217), c(89,89,216), c(90,90,216), c(91,91,215), c(92,92,214), c(93,93,214), c(94,94,213), c(95,95,213), c(96,96,212), c(97,97,212), c(98,98,211), c(98,98,210), c(99,99,210), c(100,100,209), c(101,101,209), c(102,102,208), c(103,103,208), c(104,104,208), c(105,105,207), c(105,105,207), c(106,106,206), c(107,107,206), c(108,108,205), c(109,109,205), c(110,110,204), c(110,110,204), c(111,111,204), c(112,112,203), c(113,113,203), c(114,114,202), c(114,114,202), c(115,115,202), c(116,116,201), c(117,117,201), c(118,118,200), c(118,118,200), c(119,119,200), c(120,120,199), c(121,121,199), c(121,121,199), c(122,122,198), c(123,123,198), c(124,124,198), c(124,124,197), c(125,125,197), c(126,126,197), c(127,127,196), c(128,128,196), c(128,128,195), c(129,129,195), c(130,130,195), c(130,130,194), c(131,131,194), c(132,132,194), c(133,133,193), c(133,133,193), c(134,134,193), c(135,135,192), c(136,136,192), c(136,136,192), c(137,137,191), c(138,138,191), c(139,139,191), c(139,139,190), c(140,140,190), c(141,141,190), c(142,142,189), c(142,142,189), c(143,143,189), c(144,144,188), c(144,144,188), c(145,145,188), c(146,146,187), c(147,147,187), c(147,147,187), c(148,148,186), c(149,149,186), c(149,149,186), c(150,150,185), c(151,151,185), c(152,152,185), c(152,152,184), c(153,153,184), c(154,154,184), c(154,154,183), c(155,155,183), c(156,156,182), c(157,157,182), c(157,157,182), c(158,158,181), c(159,159,181), c(159,159,181), c(160,160,180), c(161,161,180), c(162,162,180), c(162,162,179), c(163,163,179), c(164,164,178), c(164,164,178), c(165,165,178), c(166,166,177), c(167,167,177), c(167,167,176), c(168,168,176), c(169,169,176), c(169,169,175), c(170,170,175), c(171,171,174), c(172,172,174), c(172,172,173), c(173,173,173), c(174,174,173), c(174,174,172), c(175,175,172), c(176,176,171), c(177,177,171), c(177,177,170), c(178,178,170), c(179,179,169), c(179,179,169), c(180,180,168), c(181,181,168), c(181,181,167), c(182,182,167), c(183,183,166), c(184,184,166), c(184,184,165), c(185,185,165), c(186,186,164), c(186,186,164), c(187,187,163), c(188,188,163), c(189,189,162), c(189,189,162), c(190,190,161), c(191,191,161), c(191,191,160), c(192,192,159), c(193,193,159), c(194,194,158), c(194,194,158), c(195,195,157), c(196,196,157), c(196,196,156), c(197,197,155), c(198,198,155), c(199,199,154), c(199,199,153), c(200,200,153), c(201,201,152), c(201,201,151), c(202,202,151), c(203,203,150), c(204,204,149), c(204,204,149), c(205,205,148), c(206,206,147), c(206,206,146), c(207,207,146), c(208,208,145), c(209,209,144), c(209,209,143), c(210,210,143), c(211,211,142), c(211,211,141), c(212,212,140), c(213,213,139), c(214,214,138), c(214,214,138), c(215,215,137), c(216,216,136), c(216,216,135), c(217,217,134), c(218,218,133), c(219,219,132), c(219,219,131), c(220,220,130), c(221,221,129), c(221,221,128), c(222,222,127), c(223,223,126), c(224,224,125), c(224,224,124), c(225,225,123), c(226,226,122), c(226,226,121), c(227,227,119), c(228,228,118), c(229,229,117), c(229,229,116), c(230,230,114), c(231,231,113), c(232,232,112), c(232,232,110), c(233,233,109), c(234,234,107), c(234,234,106), c(235,235,104), c(236,236,103), c(237,237,101), c(237,237,100), c(238,238,98), c(239,239,96), c(239,239,94), c(240,240,92), c(241,241,91), c(242,242,89), c(242,242,86), c(243,243,84), c(244,244,82), c(245,245,80), c(245,245,77), c(246,246,74), c(247,247,72), c(247,247,69), c(248,248,65), c(249,249,62), c(250,250,58), c(250,250,54), c(251,251,49), c(252,252,44), c(253,253,37), c(253,253,28), c(254,254,13))[ round(seq(beg,end, length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/grid.hexagons.R0000644000175100001440000003221711551510077014640 0ustar hornikusers hexcoords <- function(dx, dy = NULL, n = 1, sep = NULL) { stopifnot(length(dx) == 1) if(is.null(dy)) dy <- dx/sqrt(3) if(is.null(sep)) list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0), n), y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy), n), no.sep = TRUE) else list(x = rep.int(c(dx, dx, 0, -dx, -dx, 0, sep), n), y = rep.int(c(dy,-dy, -2*dy, -dy, dy, 2*dy, sep), n), no.sep = FALSE) } hexpolygon <- function(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy=NULL, fill = 1, border = 0, hUnit = "native", ...) { ## Purpose: draw hexagon [grid.]polygon()'s around (x[i], y[i])_i ## Author: Martin Maechler, Jul 2004; Nicholas for grid n <- length(x) stopifnot(length(y) == n) stopifnot(is.list(hexC) && is.numeric(hexC$x) && is.numeric(hexC$y)) if(hexC$no.sep) { n6 <- rep.int(6:6, n) if(!is.null(hUnit)) { grid.polygon(x = unit(rep.int(hexC$x, n) + rep.int(x, n6),hUnit), y = unit(rep.int(hexC$y, n) + rep.int(y, n6),hUnit), id.lengths = n6, gp = gpar(col= border, fill= fill)) } else { grid.polygon(x = rep.int(hexC$x, n) + rep.int(x, n6), y = rep.int(hexC$y, n) + rep.int(y, n6), id.lengths = n6, gp = gpar(col= border, fill= fill)) } } else{ ## traditional graphics polygons: must be closed explicitly (+ 1 pt) n7 <- rep.int(7:7, n) polygon(x = rep.int(hexC$x, n) + rep.int(x, n7), y = rep.int(hexC$y, n) + rep.int(y, n7), ...) } } grid.hexagons <- function(dat, style = c("colorscale", "centroids", "lattice", "nested.lattice", "nested.centroids", "constant.col"), use.count=TRUE, cell.at=NULL, minarea = 0.05, maxarea = 0.8, check.erosion = TRUE, mincnt = 1, maxcnt = max(dat@count), trans = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90, end = 15) }, def.unit = "native", verbose = getOption("verbose")) { ## Warning: presumes the plot has the right shape and scales ## See plot.hexbin() ## Arguments: ## dat = hexbin object ## style = type of plotting ## 'centroids' = symbol area is a function of the count, ## approximate location near cell center of ## mass without overplotting ## 'lattice' = symbol area is a function of the count, ## plot at lattice points ## 'colorscale' = gray scale plot, ## color number determined by ## transformation and colorcut, ## area = full hexagons. ## 'nested.lattice'= plots two hexagons ## background hexagon ## area=full size ## color number by count in powers of 10 starting at pen 2 ## foreground hexagon ## area by log10(cnt)-floor(log10(cnt)) ## color number by count in powers of 10 starting at pen 12 ## 'nested.centroids' = like nested.lattice ## but counts < 10 are plotted ## ## minarea = minimum symbol area as fraction of the binning cell ## maxarea = maximum symbol area as fraction of the binning cell ## mincnt = minimum count accepted in plot ## maxcnt = maximum count accepted in plot ## trans = a transformation scaling counts into [0,1] to be applied ## to the counts for options 'centroids','lattice','colorscale': ## default=(cnt-mincnt)/(maxcnt-mincnt) ## colorcut= breaks for translating values between 0 and 1 into ## color classes. Default= seq(0,1,17), ## density = for hexagon graph paper ## border plot the border of the hexagon, use TRUE for ## hexagon graph paper ## Symbol size encoding: ## Area= minarea + scaled.count*(maxarea-minarea) ## When maxarea==1 and scaled.count==1, the hexagon cell ## is completely filled. ## ## If small hexagons are hard to see increase minarea. ## For gray scale encoding ## Uses the counts scaled into [0,1] ## Default gray cutpoints seq(0,1,17) yields 16 color classes ## The color number for the first class starts at 2. ## motif coding: black 15 white puts the first of the ## color class above the background black ## The function subtracts 1.e-6 from the lower cutpoint to include ## the boundary ## For nested scaling see the code ## Count scaling alternatives ## ## log 10 and Poisson transformations ## trans <- function(cnt) log10(cnt) ## min inv <- function(y) 10^y ## ## trans <- function(cnt) sqrt(4*cnt+2) ## inv <- function(y) (y^2-2)/4 ## Perceptual considerations. ## Visual response to relative symbol area is not linear and varies from ## person to person. A fractional power transformation ## to make the interpretation nearly linear for more people ## might be considered. With areas bounded between minarea ## and 1 the situation is complicated. ## ## The local background influences color interpretation. ## Having defined color breaks to focus attention on ## specific countours can help. ## ## Plotting the symbols near the center of mass is not only more accurate, ## it helps to reduce the visual dominance of the lattice structure. Of ## course higher resolution binning reduces the possible distance between ## the center of mass for a bin and the bin center. When symbols ## nearly fill their bin, the plot appears to vibrate. This can be ## partially controlled by reducing maxarea or by reducing ## contrast. ##____________________Initial checks_______________________ if(!is(dat,"hexbin")) stop("first argument must be a hexbin object") style <- match.arg(style) # so user can abbreviate if(minarea <= 0) stop("hexagons cannot have a zero area, change minarea") if(maxarea > 1) warning("maxarea > 1, hexagons may overplot") ##_______________ Collect computing constants______________ if(use.count){ cnt <- dat@count } else{ cnt <- cell.at if(is.null(cnt)){ if(is.null(dat@cAtt)) stop("Cell attribute cAtt is null") else cnt <- dat@cAtt } } xbins <- dat@xbins shape <- dat@shape tmp <- hcell2xy(dat, check.erosion = check.erosion) good <- mincnt <= cnt & cnt <= maxcnt xnew <- tmp$x[good] ynew <- tmp$y[good] cnt <- cnt[good] sx <- xbins/diff(dat@xbnds) sy <- (xbins * shape)/diff(dat@ybnds) ##___________Transform Counts to Radius_____________________ switch(style, "centroids" = , "lattice" = , "constant.col" =, "colorscale" = { if(is.null(trans)) { if( min(cnt,na.rm=TRUE)< 0){ pcnt<- cnt + min(cnt) rcnt <- { if(maxcnt == mincnt) rep.int(1, length(cnt)) else (pcnt - mincnt)/(maxcnt - mincnt) } } else rcnt <- { if(maxcnt == mincnt) rep.int(1, length(cnt)) else (cnt - mincnt)/(maxcnt - mincnt) } } else { rcnt <- (trans(cnt) - trans(mincnt)) / (trans(maxcnt) - trans(mincnt)) if(any(is.na(rcnt))) stop("bad count transformation") } area <- minarea + rcnt * (maxarea - minarea) }, "nested.lattice" = , "nested.centroids" = { diffarea <- maxarea - minarea step <- 10^floor(log10(cnt)) f <- (cnt/step - 1)/9 area <- minarea + f * diffarea area <- pmax(area, minarea) } ) area <- pmin(area, maxarea) radius <- sqrt(area) ##______________Set Colors_____________________________ switch(style, "centroids" = , "constant.col" = , "lattice" = { if(length(pen)!= length(cnt)){ if(is.null(pen)) pen <- rep.int(1, length(cnt)) ##else if(length(pen)== length(cnt)) break else if(length(pen)== 1) pen <- rep.int(pen,length(cnt)) else stop("'pen' has wrong length") } }, "nested.lattice" = , "nested.centroids" = { if(!is.null(pen) && length(dim(pen)) == 2) { dp <- dim(pen) lgMcnt <- ceiling(log10(max(cnt))) if(dp[1] != length(cnt) && dp[1] != lgMcnt ) { stop ("pen is not of right dimension") } if( dp[1] == lgMcnt ) { ind <- ceiling(log10(dat@count)) ## DS: 'dat' was 'bin' (??) ind[ind == 0] <- 1 pen <- pen[ind,] } ##else break } else { pen <- floor(log10(cnt)) + 2 pen <- cbind(pen, pen+10) } }, "colorscale" = { ## MM: Following is quite different from bin2d's nc <- length(colorcut) if(colorcut[1] > colorcut[nc]){ colorcut[1] <- colorcut[1] + 1e-06 colorcut[nc] <- colorcut[nc] - 1e-06 } else { colorcut[1] <- colorcut[1] - 1e-06 colorcut[nc] <- colorcut[nc] + 1e-06 } colgrp <- cut(rcnt, colorcut,labels = FALSE) if(any(is.na(colgrp))) colgrp <- ifelse(is.na(colgrp),0,colgrp) ##NL: colramp must be a function accepting an integer n ## and returning n colors clrs <- colramp(length(colorcut) - 1) pen <- clrs[colgrp] } ) ##__________________ Construct a hexagon___________________ ## The inner and outer radius for hexagon in the scaled plot inner <- 0.5 outer <- (2 * inner)/sqrt(3) ## Now construct a point up hexagon symbol in data units dx <- inner/sx dy <- outer/(2 * sy) rad <- sqrt(dx^2 + dy^2) hexC <- hexcoords(dx, dy, sep=NULL) ##_______________ Full Cell Plotting_____________________ switch(style, "constant.col" = , "colorscale" = { hexpolygon(xnew, ynew, hexC, density = density, fill = pen, border = if(!is.null(border)) border else pen) ## and that's been all for these styles return(invisible(paste("done", sQuote(style)))) }, "nested.lattice" = , "nested.centroids" = { hexpolygon(xnew, ynew, hexC, density = density, fill = if (is.null(border) || border) 1 else pen[,1], border = pen[,1]) } ) ##__________________ Symbol Center adjustments_______________ if(style == "centroids" || style == "nested.centroids") { xcm <- dat@xcm[good] ycm <- dat@ycm[good] ## Store 12 angles around a circle and the replicate the first ## The actual length for these vectors is determined by using ## factor use below k <- sqrt(3)/2 cosx <- c(1, k, .5, 0, -.5, -k, -1, -k, -.5, 0, .5, k, 1)/sx siny <- c(0, .5, k, 1, k, .5, 0, -.5, -k, -1, -k, -.5, 0)/sy ## Compute distances for differences after scaling into ## [0,size] x [0,aspect*size] ## Then there are size hexagons on the x axis dx <- sx * (xcm - xnew) dy <- sy * (ycm - ynew) dlen <- sqrt(dx^2 + dy^2) ## Find the closest approximating direction of the 12 vectors above cost <- ifelse(dlen > 0, dx/dlen, 0) tk <- (6 * acos(cost))/pi tk <- round(ifelse(dy < 0, 12 - tk, tk)) + 1 ## Select the available length for the approximating vector hrad <- ifelse(tk %% 2 == 1, inner, outer) ## Rad is either an inner or outer approximating radius. ## If dlen + hrad*radius <= hrad, move the center dlen units. ## Else move as much of dlen as possible without overplotting. fr <- pmin(hrad * (1 - radius), dlen) # Compute the symbol centers ## fr is the distance for the plot [0,xbins] x [0,aspect*xbins] ## cosx and siny give the x and y components of this distance ## in data units xnew <- xnew + fr * cosx[tk] ynew <- ynew + fr * siny[tk] } ## ________________Sized Hexagon Plotting__________________ ## scale the symbol by radius and add to the new center n <- length(radius) if(verbose) cat('length = ',length(pen),"\n", 'pen = ', pen+1,"\n") ##switch(style, ## centroids = , ## lattice = {if(is.null(pen))pen <- rep.int(1, n) ## else pen <- rep.int(pen, n)}, ## nested.lattice = , ## nested.centroids ={ ## if( ## pen[,2] <- pen[,1] + 10 ## } ) ## grid.polygon() closes automatically: now '6' where we had '7': n6 <- rep.int(6:6, n) pltx <- rep.int(hexC$x, n) * rep.int(radius, n6) + rep.int(xnew, n6) plty <- rep.int(hexC$y, n) * rep.int(radius, n6) + rep.int(ynew, n6) switch(style, "centroids" = , "lattice" = { grid.polygon(pltx, plty, default.units=def.unit, id=NULL, ## density = density, id.lengths= n6, gp=gpar(fill = pen, col = border)) }, "nested.lattice" = , "nested.centroids" = { grid.polygon(pltx, plty, default.units=def.unit, id=NULL, id.lengths= n6, gp=gpar(fill = pen[,2], ## density = density, col=if(!is.null(border)) border else pen[,2])) }) } if(FALSE){ ## considering 'hexagons' object setMethod("hexagons", signature(dat="hexbin"), grid.hexagons) erode.hexagons <- function(ebin,pen="black",border="red"){ print("Blank for now") } } hexbin/R/hexplom.R0000644000175100001440000002617012371211714013552 0ustar hornikuserspanel.hexplom <- function(...) panel.hexbinplot(...) hexplom <- function(x, data, ...) { UseMethod("hexplom") } hexplom.data.frame <- function (x, data = NULL, ..., groups = NULL, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() if (!is.null(ccall$data)) warning("explicit 'data' specification ignored") ccall$data <- list(x = x, groups = groups, subset = subset) ccall$x <- ~x ccall$groups <- groups ccall$subset <- subset ccall[[1]] <- quote(hexbin::hexplom) ans <- eval.parent(ccall) ans$call <- ocall ans } hexplom.matrix <- function (x, data = NULL, ..., groups = NULL, subset = TRUE) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() if (!is.null(ccall$data)) warning("explicit 'data' specification ignored") ccall$data <- list(x = x, groups = groups, subset = subset) ccall$x <- ~x ccall$groups <- groups ccall$subset <- subset ccall[[1]] <- quote(hexbin::hexplom) ans <- eval.parent(ccall) ans$call <- ocall ans } hexplom.formula <- function(x, data = NULL, ...) { ocall <- sys.call(sys.parent()) ocall[[1]] <- quote(hexplom) ccall <- match.call() ccall[[1]] <- quote(lattice::splom) if (is.null(ccall$panel)) ccall$panel <- panel.hexplom ans <- eval.parent(ccall) ans$call <- ocall ans } old.hexplom.formula <- function(x, data = parent.frame(), auto.key = FALSE, aspect = 1, between = list(x = 0.5, y = 0.5), #panel = if (is.null(groups)) "panel.hexplom" #else "panel.superpose", panel = panel.hexplom, prepanel = NULL, scales = list(), strip = TRUE, groups = NULL, xlab = "Scatter Plot Matrix", xlim, ylab = NULL, ylim, superpanel = "panel.pairs", pscales = 5, varnames, drop.unused.levels = lattice.getOption("drop.unused.levels"), ..., default.scales = list(draw = FALSE, relation = "same", axs = "i"), subset = TRUE) { ## dots <- eval(substitute(list(...)), data, parent.frame()) dots <- list(...) #groups <- eval(substitute(groups), data, parent.frame()) if(!is.null(groups))stop("groups not implemented yet") subset <- eval(substitute(subset), data, parent.frame()) ## Step 1: Evaluate x, y, etc. and do some preprocessing ## right.name <- deparse(substitute(formula)) ## formula <- eval(substitute(formula), data, parent.frame()) form <- ## if (inherits(formula, "formula")) latticeParseFormula(x, data, subset = subset, groups = groups, multiple = FALSE, outer = FALSE, subscripts = TRUE, drop = drop.unused.levels) ## else { ## if (is.matrix(formula)) { ## list(left = NULL, ## right = as.data.frame(formula)[subset,], ## condition = NULL, ## left.name = "", ## right.name = right.name, ## groups = groups, ## subscr = seq(length = nrow(formula))[subset]) ## } ## else if (is.data.frame(formula)) { ## list(left = NULL, ## right = formula[subset,], ## condition = NULL, ## left.name = "", ## right.name = right.name, ## groups = groups, ## subscr = seq(length = nrow(formula))[subset]) ## } ## else stop("invalid formula") ## } ## We need to be careful with subscripts here. It HAS to be there, ## and it's to be used to index x, y, z (and not only groups, ## unlike in xyplot etc). This means we have to subset groups as ## well, which is about the only use for the subscripts calculated ## in latticeParseFormula, after which subscripts is regenerated ## as a straight sequence indexing the variables if (!is.null(form$groups)) groups <- form$groups[form$subscr] subscr <- seq(length = nrow(form$right)) if (!is.function(panel)) panel <- eval(panel) if (!is.function(strip)) strip <- eval(strip) prepanel <- if (is.function(prepanel)) prepanel else if (is.character(prepanel)) get(prepanel) else eval(prepanel) cond <- form$condition number.of.cond <- length(cond) x <- as.data.frame(form$right) if (number.of.cond == 0) { strip <- FALSE cond <- list(as.factor(rep(1, nrow(x)))) number.of.cond <- 1 } if (!missing(varnames)) colnames(x) <- eval(substitute(varnames), data, parent.frame()) ## create a skeleton trellis object with the ## less complicated components: #foo <- do.call(lattice:::trellis.skeleton, foo <- do.call(trellis.skeleton, c(list(cond = cond, aspect = aspect, between = between, panel = superpanel, strip = strip, xlab = xlab, ylab = ylab, xlab.default = "Scatter Plot Matrix"), dots)) dots <- foo$dots # arguments not processed by trellis.skeleton foo <- foo$foo foo$call <- match.call() ## Step 2: Compute scales.common (leaving out limits for now) ## FIXME: It is not very clear exactly what effect scales is ## supposed to have. Not much in Trellis (probably), but there are ## certain components which are definitely relevant, and certain ## others (like log) which can be used in innovative ## ways. However, I'm postponing all that to later, if at all if (!is.list(scales)) scales <- list() ## some defaults for scales # if (is.null(scales$draw)) scales$draw <- FALSE # if (is.null(scales$relation)) scales$relation <- "same" # if (is.null(scales$axs)) scales$axs <- "i" scales <- updateList(default.scales, scales) foo <- c(foo, #do.call(lattice:::construct.scales, scales)) do.call(construct.scales, scales)) ## Step 3: Decide if limits were specified in call: have.xlim <- !missing(xlim) if (!is.null(foo$x.scales$limit)) { have.xlim <- TRUE xlim <- foo$x.scales$limit } have.ylim <- !missing(ylim) if (!is.null(foo$y.scales$limit)) { have.ylim <- TRUE ylim <- foo$y.scales$limit } ## Step 4: Decide if log scales are being used (has to be NO): have.xlog <- !is.logical(foo$x.scales$log) || foo$x.scales$log have.ylog <- !is.logical(foo$y.scales$log) || foo$y.scales$log ## immaterial, since scales has no effect. # if (have.xlog) { # xlog <- foo$x.scales$log # xbase <- # if (is.logical(xlog)) 10 # else if (is.numeric(xlog)) xlog # else if (xlog == "e") exp(1) # # x <- log(x, xbase) # if (have.xlim) xlim <- log(xlim, xbase) # } # if (have.ylog) { # ylog <- foo$y.scales$log # ybase <- # if (is.logical(ylog)) 10 # else if (is.numeric(ylog)) ylog # else if (ylog == "e") exp(1) # # y <- log(y, ybase) # if (have.ylim) ylim <- log(ylim, ybase) # } ## Step 5: Process cond cond.max.level <- unlist(lapply(cond, nlevels)) ## id.na used only to see if any plotting is needed. Not used ## subsequently, unlike other functions id.na <- FALSE for (j in 1:ncol(x)) id.na <- id.na | is.na(x[,j]) for (var in cond) id.na <- id.na | is.na(var) if (!any(!id.na)) stop("nothing to draw") ## Nothing simpler ? ## Step 6: Evaluate layout, panel.args.common and panel.args foo$panel.args.common <- c(list(z = x, panel = panel, panel.subscripts = TRUE, groups = groups, # xscales = foo$x.scales, yscales =foo$y.scales, .aspect.ratio=aspect, pscales = pscales), dots) nplots <- prod(cond.max.level) if (nplots != prod(sapply(foo$condlevels, length))) stop("mismatch") foo$panel.args <- vector(mode = "list", length = nplots) cond.current.level <- rep(1, number.of.cond) for (panel.number in seq(length = nplots)) { ##id <- !id.na WHY ? for(i in 1:number.of.cond) { var <- cond[[i]] id <- if (is.shingle(var)) ((var >= levels(var)[[cond.current.level[i]]][1]) & (var <= levels(var)[[cond.current.level[i]]][2])) else (as.numeric(var) == cond.current.level[i]) } foo$panel.args[[panel.number]] <- list(subscripts = subscr[id]) cond.current.level <- #lattice:::cupdate(cond.current.level, cond.max.level) cupdate(cond.current.level, cond.max.level) } #more.comp <- c(lattice:::limits.and.aspect( more.comp <- c(limits.and.aspect( lattice::prepanel.default.splom, prepanel = prepanel, have.xlim = have.xlim, xlim = xlim, have.ylim = have.ylim, ylim = ylim, x.relation = foo$x.scales$relation, y.relation = foo$y.scales$relation, panel.args.common = foo$panel.args.common, panel.args = foo$panel.args, aspect = aspect, nplots = nplots, x.axs = foo$x.scales$axs, y.axs = foo$y.scales$axs), #lattice::: cond.orders(foo)) cond.orders(foo)) foo[names(more.comp)] <- more.comp if (is.null(foo$legend) && !is.null(groups) && (is.list(auto.key) || (is.logical(auto.key) && auto.key))) { foo$legend <- list(list(fun = "drawSimpleKey", args = updateList(list(text = levels(as.factor(groups)), points = TRUE, rectangles = FALSE, lines = FALSE), if (is.list(auto.key)) auto.key else list()))) foo$legend[[1]]$x <- foo$legend[[1]]$args$x foo$legend[[1]]$y <- foo$legend[[1]]$args$y foo$legend[[1]]$corner <- foo$legend[[1]]$args$corner names(foo$legend) <- if (any(c("x", "y", "corner") %in% names(foo$legend[[1]]$args))) "inside" else "top" if (!is.null(foo$legend[[1]]$args$space)) names(foo$legend) <- foo$legend[[1]]$args$space } class(foo) <- "trellis" foo } hexbin/R/LINGRAY.R0000644000175100001440000000461711551510077013210 0ustar hornikusersLinGray <- function(n,beg = 1,end = 92) { if(beg < 1 || end < 1 || beg > 256 || end > 256) stop("`beg' and `end' must be numbers in the interval [1,256]") M <- rbind(c(0,0,0), c(0,0,0), c(1,1,1), c(1,1,1), c(2,2,2), c(3,3,3), c(4,4,4), c(5,5,5), c(6,6,6), c(7,7,7), c(8,8,8), c(9,9,9), c(10,10,10), c(11,11,11), c(12,12,12), c(13,13,13), c(14,14,14), c(15,15,15), c(16,16,16), c(17,17,17), c(18,18,18), c(19,19,19), c(20,20,20), c(21,21,21), c(22,22,22), c(23,23,23), c(24,24,24), c(25,25,25), c(26,26,26), c(27,27,27), c(28,28,28), c(29,29,29), c(30,30,30), c(32,32,32), c(34,34,34), c(35,35,35), c(37,37,37), c(39,39,39), c(41,41,41), c(43,43,43), c(45,45,45), c(46,46,46), c(47,47,47), c(49,49,49), c(51,51,51), c(52,52,52), c(54,54,54), c(56,56,56), c(59,59,59), c(61,61,61), c(64,64,64), c(67,67,67), c(69,69,69), c(72,72,72), c(75,75,75), c(76,76,76), c(78,78,78), c(81,81,81), c(84,84,84), c(87,87,87), c(91,91,91), c(94,94,94), c(97,97,97), c(101,101,101), c(104,104,104), c(107,107,107), c(108,108,108), c(112,112,112), c(116,116,116), c(120,120,120), c(124,124,124), c(128,128,128), c(132,132,132), c(136,136,136), c(141,141,141), c(145,145,145), c(147,147,147), c(150,150,150), c(154,154,154), c(159,159,159), c(164,164,164), c(169,169,169), c(174,174,174), c(179,179,179), c(185,185,185), c(190,190,190), c(195,195,195), c(201,201,201), c(207,207,207), c(212,212,212), c(216,216,216), c(218,218,218), c(224,224,224), c(226,226,226), c(230,230,230), c(237,237,237), c(243,243,243), c(245,245,245), c(252,252,252), c(255,255,255), c(255,255,255))[round(seq(beg,end,length = n)), ] rgb(M[,1]/255, M[,2]/255, M[,3]/255) } hexbin/R/hexViewport.R0000644000175100001440000002165612434727512014436 0ustar hornikuserssetOldClass("unit") setOldClass("viewport") smartBnds <- function(hbin, eps=.05) { hxy <- hcell2xy(hbin) xr <- range(hxy$x) yr <- range(hxy$y) dx <- diff(xr) dy <- diff(yr) lambda <- function(a) pmax(log(a), 1) epsx <- c(-1,1)*(dx*eps/lambda(dx)) epsy <- c(-1,1)*(dy*eps/lambda(dy)) sx <- hbin@xbins/diff(hbin@xbnds) sy <- (hbin@xbins * hbin@shape)/diff(hbin@ybnds) inner <- 0.5 outer <- 1/sqrt(3) dx <- inner/sx dy <- outer/sy #xb <- dx/(hbin@xbins+1) #yb <- dy/((1/sqrt(3))*(hbin@xbins+1)*hbin@shape) list(xr = xr+ c(-dx,dx)+ epsx, yr = yr+ c(-dy,dy)+ epsy) } rname <- function(n, chars = letters) { ## random name with n characters paste(sample(chars, size = n, replace = TRUE), collapse="") } setClass("hexVP", representation(hexVp.on = "viewport", hexVp.off = "viewport", mar = "unit", fig = "unit", plt = "unit", xscale = "numeric", yscale = "numeric",shape="numeric", hp.name="character") ) hexViewport <- function(x, offset = unit(0,"inches"), mar = NULL, xbnds = NULL, ybnds = NULL, newpage = FALSE, clip ="off", vp.name=NULL) { if(!is(x,"hexbin")) stop("first argument must be a hexbin object.") stopifnot(is.unit(offset)) hvp <- new("hexVP") if (newpage) grid.newpage() if(is.null(mar)) { mar <- unit(0.1 + c(5,4,4,2),"lines") } else { if(!is.unit(mar)) stop("'mar' must be specified in unit()s") if(length(mar) == 1) mar <- rep(mar, 4) else if(length(mar) != 4) stop("'mar' must have length 1 or 4") } ## in both cases mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) fig <- c(as.numeric(convertUnit(unit(vpin[1],"inches") - offset,"inches")), as.numeric(vpin[2])) pin <- c(fig[1]-mai[2]-mai[4], fig[2]-mai[1]-mai[3]) xsize <- pin[1] ysize <- pin[2] ## The point is to optimize the placement ## and plotting area of the plotting window with ## the constraint that the margins are preserved ## to within some epsilon. This is going to get even ## harder for cases where the complex layouts are ## being constructed. NL -- I think it is fixed now (NL --3/22/2005) ## Now find the maximum rectangle in fig that ## has the correct aspect ratio and does not spill over epsilon into ## the margins, i.e. ysize/xsize - aspect.ratio < eps and ## xsize < fig[1], ysize < fig[2] if(x@shape * xsize <= ysize) { ##center <- (ysize - x@shape * xsize)/2 center <- (ysize - x@shape * xsize)/2 mai[1] <- mai[1] + center mai[3] <- mai[3] + center ysize <- x@shape * xsize } else { center <- (xsize - ysize/x@shape)/2 mai[2] <- mai[2] + center mai[4] <- mai[4] + center xsize <- ysize/x@shape } ##fig <- c(pin[1]+mai[2]+ mai[4],fig[2]) pin <- c(xsize,ysize) mar <- c(convertUnit(unit(mai[1],"inches"),"lines"), convertUnit(unit(mai[2],"inches"),"lines"), convertUnit(unit(mai[3],"inches"),"lines"), convertUnit(unit(mai[4],"inches"),"lines")) ##pin <- c(fig[1]-(mai[2] + mai[4]), ## fig[2]-(mai[1] + mai[3])) margins <- rep(as.numeric(mar), length.out = 4) wd <- convertUnit(unit(pin[1],"inches"),"npc") ## (unit(sum(margins[c(2, 4)]), "lines") + ## convertUnit(unit(legend,"inches"),"lines")) ## Oy, mi stupido! This is the problem, need to get the bounds right ## here. Fixed, do we need to guard against others stupidity and put some ## checks on xbnds and ybnds? (NL,4/1/2005) if(is.null(vp.name)) vp.name <- rname(5) xyb <- smartBnds(x) hvp@xscale <- xs <- if(is.null(xbnds)) xyb$xr else xbnds hvp@yscale <- ys <- if(is.null(ybnds)) xyb$yr else ybnds ht <- unit(1, "npc") - unit(sum(margins[c(1,3)]), "lines") hvp@hexVp.off <- viewport(x = unit(margins[2], "lines"), y = unit(margins[1], "lines"), width = wd, height = ht, xscale = xs, yscale = ys, just = c("left", "bottom"), default.units = "native", clip = "off", name = paste(vp.name,".off",sep="")) hvp@hexVp.on <- viewport(x = unit(margins[2], "lines"), y = unit(margins[1], "lines"), width = wd, height = ht, xscale = xs, yscale = ys, just = c("left", "bottom"), default.units = "native", clip = "on", name = paste(vp.name,".on",sep="")) hvp@mar <- unit(mar,"lines") hvp@fig <- convertUnit(unit(fig,"inches"),"npc") hvp@plt <- convertUnit(unit(pin,"inches"),"npc") hvp@shape <- x@shape ##hvp@leg <-convertUnit(offset,"npc") hvp } ## Potentially: ## setGeneric("grid:::pushViewport") ## setMethod("pushViewport", signature(x="hexVP"), ## function(hvp) { pushViewport(hvp@hexVp) }) pushHexport <- function(hvp, clip="off") { if(!is(hvp, "hexVP")) stop("1st argument must be 'hexVP' object") pushViewport(if(clip=="on") hvp@hexVp.on else hvp@hexVp.off) } ## maybe in the future ## setMethod("push",signature("hexVP"), pushHexport) setGeneric("getMargins", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getMargins")) setMethod("getMargins", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ mar <- convertUnit(x@mar,ret.unit) if(numeric) as.numeric(mar) else mar }) setGeneric("getPlt", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getPlt")) setMethod("getPlt", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ plt <- convertUnit(x@plt,ret.unit) if(numeric) as.numeric(plt) else plt }) setGeneric("getFig", function(x, ret.unit = "npc", numeric = FALSE) standardGeneric("getFig")) setMethod("getFig", "hexVP", function(x, ret.unit = "npc", numeric = FALSE){ fig <- convertUnit(x@fig,ret.unit) if(numeric) as.numeric(fig) else fig }) ## MM doesn't think it's ok to "pollute" the generic-space ## just for basic slot accessors : ## setGeneric("getXscale", function(x)standardGeneric("getXscale")) ## setMethod("getXscale", "hexVP", function(x){ x@xscale }) ## setGeneric("getYscale", function(x)standardGeneric("getYscale")) ## setMethod("getYscale", "hexVP", function(x){ x@yscale }) hexVP.abline <- function(hvp, a = NULL, b = NULL, h = numeric(0), v = numeric(0), col = 'black', lty = 1, lwd = 2, ...) { pushHexport(hvp, clip = 'on') col.line <- col if (!is.null(a)) { if (inherits(a, "lm")) { coeff <- coef(a) } else if (!is.null(tryCatch(coef(a), error = function(e) NULL))) coeff <- coef(a) else coeff <- c(a, b) if (length(coeff) == 1) coeff <- c(0, coeff) if (coeff[2] == 0) h <- c(h, coeff[1]) else if (!any(is.null(coeff))) { xx <- current.viewport()$xscale yy <- current.viewport()$yscale x <- numeric(0) y <- numeric(0) ll <- function(i, j, k, l) (yy[j] - coeff[1] - coeff[2] * xx[i]) * (yy[l] - coeff[1] - coeff[2] * xx[k]) if (ll(1, 1, 2, 1) <= 0) { y <- c(y, yy[1]) x <- c(x, (yy[1] - coeff[1])/coeff[2]) } if (ll(2, 1, 2, 2) <= 0) { x <- c(x, xx[2]) y <- c(y, coeff[1] + coeff[2] * xx[2]) } if (ll(2, 2, 1, 2) <= 0) { y <- c(y, yy[2]) x <- c(x, (yy[2] - coeff[1])/coeff[2]) } if (ll(1, 2, 1, 1) <= 0) { x <- c(x, xx[1]) y <- c(y, coeff[1] + coeff[2] * xx[1]) } if (length(x) > 0) grid.lines(x = x, y = y, default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) } } h <- as.numeric(h) v <- as.numeric(v) for (i in seq(along = h)) grid.lines(y = rep(h[i], 2), default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) for (i in seq(along = v)) grid.lines(x = rep(v[i], 2), default.units = "native", gp = gpar(col = col.line, lty = lty, lwd = lwd)) popViewport() } hexVP.loess <- function(hbin, hvp = NULL, span = 0.4, col = 'red', n = 200) { fit <- loess(hbin@ycm ~ hbin@xcm, weights = hbin@count, span = span) if(!is.null(hvp)) { pushHexport(hvp, clip = 'on') # grid.lines(seq(0,16, length = n), # predict(fit,seq(0,16, length = n)), # gp = gpar(col = col), default.units = 'native') grid.lines(seq(hbin@xbnds[1], hbin@xbnds[2], length = n), predict(fit,seq(hbin@xbnds[1], hbin@xbnds[2], length = n)), gp = gpar(col = col), default.units = 'native') popViewport() } invisible(fit) } hexbin/vignettes/0000755000175100001440000000000012565116271013563 5ustar hornikusershexbin/vignettes/hexagon_binning.Rnw0000644000175100001440000005204112550230437017405 0ustar hornikusers%% Emacs: use Rnw-mode if available, else noweb %% NOTE -- ONLY EDIT THE .Rnw FILE ! %\VignetteIndexEntry{Hexagon Binning} %\VignetteDepends{hexbin, grid, marray} %\VignetteKeywords{Over plotting, Large data set, Visualization} %\VignettePackage{hexbin} \documentclass[]{article} \usepackage[authoryear,round]{natbib} \usepackage{amsmath} \usepackage{hyperref} \author{Nicholas Lewin-Koh\footnote{with minor assistance by Martin M\"achler}} \begin{document} \title{Hexagon Binning: an Overview} \maketitle{} \section{Overview} Hexagon binning is a form of bivariate histogram useful for visualizing the structure in datasets with large $n$. The underlying concept of hexagon binning is extremely simple; \begin{enumerate} \item the $xy$ plane over the set (range($x$), range($y$)) is tessellated by a regular grid of hexagons. \item the number of points falling in each hexagon are counted and stored in a data structure \item the hexagons with count $ > 0$ are plotted using a color ramp or varying the radius of the hexagon in proportion to the counts. \end{enumerate} The underlying algorithm is extremely fast and effective for displaying the structure of datasets with $n \ge 10^6$. If the size of the grid and the cuts in the color ramp are chosen in a clever fashion than the structure inherent in the data should emerge in the binned plots. The same caveats apply to hexagon binning as apply to histograms and care should be exercised in choosing the binning parameters. The hexbin package is a set of function for creating, manipulating and plotting hexagon bins. The package extends the basic hexagon binning ideas with several functions for doing bivariate smoothing, finding an approximate bivariate median, and looking at the difference between two sets of bins on the same scale. The basic functions can be incorporated into many types of plots. This package is based on the original package for S-PLUS by Dan Carr at George Mason University and is mostly the fruit of his graphical genius and intuition. \section{Theory and Algorithm} Why hexagons? There are many reasons for using hexagons, at least over squares. Hexagons have symmetry of nearest neighbors which is lacking in square bins. Hexagons are the maximum number of sides a polygon can have for a regular tesselation of the plane, so in terms of packing a hexagon is 13\% more efficient for covering the plane than squares. This property translates into better sampling efficiency at least for elliptical shapes. Lastly hexagons are visually less biased for displaying densities than other regular tesselations. For instance with squares our eyes are drawn to the horizontal and vertical lines of the grid. The following figure adapted from \cite[]{carretal}shows this effectively. \begin{figure}[h] \centering <>= library("grid") library("hexbin") x <- rnorm(1000) y <- rnorm(1000) ##-- Hexagon Bins: -- hbin <- hexbin(x,y, xbins = 25) grid.newpage() pushViewport(viewport(layout=grid.layout(1, 2))) pushViewport(viewport(layout.pos.col=1,layout.pos.row=1)) plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE) popViewport() ##-- Manual "square" binning: -- ## grid rx <- range(x); bx <- seq(rx[1],rx[2], length=29) ry <- range(y); by <- seq(ry[1],ry[2], length=29) ## midpoints mx <- (bx[-1]+bx[-29])/2 my <- (by[-1]+by[-29])/2 gg <- as.matrix(expand.grid(mx,my))# dim = (28^2, 2) zz <- unname(table(cut(x, b = bx), cut(y, b = by)))# 28 x 28 ind <- zz > 0 if(FALSE) ## ASCII image: symnum(unname(ind)) sq.size <- zz[ind]^(1/3) / max(zz) ## if we used base graphics: ## symbols(gg[ind,], squares = sq.size, inches = FALSE, fg = 2, bg = 2) pushViewport(viewport(layout.pos.col=2, layout.pos.row=1)) vp <- plot(hbin, style="lattice", legend=0, xlab = "X", ylab = "Y", newpage=FALSE, type="n") pushHexport(vp$plot, clip="on") grid.rect(x= gg[ind,1], y=gg[ind,2], width = sq.size, height= sq.size, default.units = "native", gp = gpar(col="black",fill="black")) popViewport() @ \caption[bivariate: squares and hexagons]{A bivariate point set binned into squares and hexagons. Bins are scaled approximately equal, and the size of the glyph is proportional to the count in that bin.} \label{fig:compHexSq} \end{figure} We can see in Figure~\ref{fig:compHexSq} that when the data are plotted as squares centered on a regular lattice our eye is drawn to the regular lines which are parallel to the underlying grid. Hexagons tend to break up the lines. How does does the hexagon binning algorithm work? \begin{enumerate} \item Squash $Y$ by $\sqrt{3}$ \item Create a dual lattice \item Bin each point into pair of near neighbor rectangles \item Pick closest of the rectangle centers (adjusting for $\sqrt{3}$) \end{enumerate} << nearNeighbor, echo = false, results = hide >>= x <- -2:2 sq <- expand.grid(list(x = x, y = c(-1,0,1))) fc.sq <- rbind(sq,sq+.5) # face centered squares fc.sq$y <- sqrt(3)*fc.sq$y # stretch y by the sqrt(3) nr <- length(fc.sq$x)/2 @ \begin{figure}[h] \centering << fig = TRUE,width = 4,height = 8,echo = FALSE >>= par(mfrow = c(3,1)) par(mai = c(.1667,0.2680,0.1667,0.2680)) ##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) points(-.25,.15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1)+1 py <- sqrt(3)*(c(0,0,-1,-1)+1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) points(-.25, .15, col = 2, pch = 16, cex = .5) par(mai = c(.1667, 0.2680, 0.1667, 0.2680))##par(mai=.25*par("mai")) plot(fc.sq$x, fc.sq$y, pch = 16, cex = .5) nr <- length(fc.sq$x)/2 points(fc.sq$x[1:nr], fc.sq$y[1:nr], pch = 15, cex = .7, col = 5) px <- c(-1,-2,-2,-1) + 1 py <- sqrt(3)*(c(0,0,-1,-1) + 1) polygon(px, py, density = 0, col = 5) polygon(px+.5, py-sqrt(3)/2, density = 0) px <- c(-.5,-.5,0,.5, .5, 0) py <- c(-.5, .5,1,.5,-.5,-1) /sqrt(3) polygon(px, py, col = gray(.5), density = 0) polygon(px-.5, py+sqrt(3)/2, density = 0, col = 4) points(-.25, .15, col = 2, pch = 16, cex = .5) plot.new() arrows(-.25, .15, 0, 0, angle = 10, length = .05) @ \caption[Near Neighbor Rectangles]{} \label{fig:binalg} \end{figure} Figure~\ref{fig:binalg} shows graphically how the algorithm works. In the first panel we see the the dual lattice laid out in black and blue points. The red point is an arbitrary point to be binned. The second panel shows the near neigbor rectangles for each lattice around the point to be binned, the intersection of the rectangles contains the point. The last panel shows the simple test for locating the point in the hexagon, the closest of the two corners which are not intersections is the center of the hexagon to which the point should be allocated. The binning can be calculated in one pass through the data, and is clearly $O(n)$ with a small constant. Storage is vastly reduced compared to the original data. \section{Basic Hexagon Binning Functions} Using the basic hexagon binning functions are not much more involved than using the basic plotting functions. The following little example shows the basic features of the basic plot and binning functions. We start by loading the package and generating a toy example data set. << basic, fig = TRUE, results = hide >>= x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40) plot(hbin) @ There are two things to note here. The first is that the function \texttt{gplot.hexbin} is defined as a \texttt{plot} method for the S4 class \texttt{hexbin}. The second is that the default color scheme for the hexplot is a gray scale. However, there is an argument to plot, \texttt{colramp}, that allows the use of any function that excepts an argument \texttt{n} and returns $n$ colors. Several functions are supplied that provide alternative color-ramps to R's built in color ramp functions, see \texttt{help(ColorRamps)}. << showcol, fig = TRUE, width = 7, height = 4, echo = FALSE >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"),"inches"), convertHeight(unit(1,"npc"),"inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) x <- rnorm(20000) y <- rnorm(20000) hbin <- hexbin(x,y, xbins = 40, shape = shape) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = terrain.colors) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hbin, legend = 0, xlab = "X", ylab = "Y", newpage = FALSE, colramp = BTY) popViewport() @ The figure shows three examples of using hexagons in a plot for large $n$ with different color schemes. Upper left: the default gray scale, upper right: the R base \texttt{terrain.colors()}, and lower middle: \texttt{BTY()}, a blue to yellow color ramp supplied with hexbin on a perceptually linear scale. The hexbin package supplies a plotting method for the hexbin data structure. The plotting method \texttt{gplot.hexbin} accepts all the parameters for the hexagon function and supplies a legend as well, for easy interpretation of the plot. Figure~2 shows a hex binned plot with a legend. A function \texttt{grid.hexlegend} is supplied for creating user specified hexagon legends. \section{Extended Hexagon Functions} So far we have looked at the basic hexagon plot. The hexbin package supplies several extensions to the basic hexbin, and the associated hexplot. The extensions discussed in this section will be smoothing hexbin objects using the hsmooth function, approximating a bivariate median with hexagons and a version of a bivariate boxplot, and using eroded hexbin objects to look at the overlap of two bivariate populations. \subsection{Smoothing with \texttt{hsmooth}} At this point the hexbin package only provides a single option for smoothing using a discrete kernel. Several improvements are in development including an apply function over neighborhoods and spline functions using a hexagonal basis or tensor products. The apply function should facilitate constructing more sophisticated kernel smoothers. The hexagon splines will provide an alternative to smoothing on a square grid and allow interpolation of hexagons to finer grids. The current implementation uses the center cell, immediate neighbors and second neighbors to smooth the counts. The counts for each resulting cell is a linear combination of the counts in the defined neighborhood, including the center cell and weights. The counts are blurred over the the domain, and the domain increases because of shifting. Generally the dimension of the occupied cells of the lattice increases by one, sometimes two. Some examples of using the hsmooth function are given below. Notice in the plots that the first plot is with no smoothing, weights are \texttt{c(1,0,0)} meaning that only the center cell is used with identity weights. The second plot shows a first order kernel using weights \texttt{c(24,12,0)}, while the third plot uses weights for first and second order neighbors specified as \texttt{c(48,24,12)}. The code segment generating these plots rescales the smoothed counts so that they are on the original scale. << showsmth, fig = TRUE, width = 8, height = 4, echo = FALSE >>= #nf <- layout(matrix(c(1,1,2,2,4,3,3,4), ncol=4, nrow=2, byrow=TRUE), # widths = rep(1,4), heights=rep(1,2)) x <- rnorm(10000) y <- rnorm(10000) grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) vpin <- c(convertWidth (unit(1,"npc"), "inches"), convertHeight(unit(1,"npc"), "inches")) shape <- optShape(height = vpin[2],width = vpin[1]/3,mar = mai) hbin <- hexbin(x,y, xbins = 30,shape = shape) hsmbin1 <- hsmooth(hbin, c( 1, 0,0)) hsmbin2 <- hsmooth(hbin, c(24,12,0)) hsmbin2@count <- as.integer(ceiling(hsmbin2@count/sum(hsmbin2@wts))) hsmbin3 <- hsmooth(hbin,c(48,24,12)) hsmbin3@count <- as.integer(ceiling(hsmbin3@count/sum(hsmbin3@wts))) pushViewport(viewport(layout = grid.layout(1, 3))) pushViewport(viewport(layout.pos.col = 1, layout.pos.row = 1)) plot(hsmbin1, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) plot(hsmbin2, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() pushViewport(viewport(layout.pos.col = 3,layout.pos.row = 1)) plot(hsmbin3, legend = 0, xlab = "X", ylab = "Y", newpage= FALSE,colramp = BTY) popViewport() @ \subsection{Bin Erosion and the \texttt{hboxplot}} The next tool to introduce, gray level erosion, extends the idea of the boxplot. The idea is to extract cells in a way that the most exposed cells are removed first, ie cells with fewer neighbors, but cells with lower counts are removed preferentially to cells with higher counts. The algorithm works as follows: Mark the high count cells containing a given fraction, cdfcut, of the total counts. Mark all the cells if cdfcut is zero. The algorithm then performs gray-level erosion on the marked cells. Each erosion cycle removes counts from cells. The counts removed from each cell are a multiple of the cell's exposed-face count. The algorithm chooses the multiple so at least one cell will be empty or have a count deficit on each erosion cycle. The erode vector contains an erosion number for each cell. The value of erode is \begin{center} $6\times$(The erosion cycle at cell removal) $ - $ (The cell deficit at removal) \end{center} The cell with the highest erosion number is a candidate bivariate median. A few ties in the erosion order are common. The notion of an ordering to the median is nice because it allows us to create a version of a bivariate box plot built on hexagons. The following example comes from a portion of the ''National Health and Nutrition Examination Survey'' included in \texttt{hexbin} as the sample data set NHANES. The data consist of 9575 persons and mesures various clinical factors. Here in Figure~\ref{hbox} we show the levels of transferin, a measure of iron binding against hemoglobin for all \begin{figure}[h] \centering << echo = FALSE >>= data(NHANES) #grid.newpage() mar <- unit(0.1 + c(5,4,4,2),"lines") mai <- as.numeric(convertUnit(mar, "inches")) #vpin <- c(convertWidth (unit(1,"npc"), "inches"), # convertHeight(unit(1,"npc"), "inches")) vpin <- c(unit(6,"inches"),unit(4, "inches")) shape <- optShape(height = vpin[2], width = vpin[1], mar = mai) @ << hbox, fig = TRUE, width = 6, height = 4, echo = FALSE >>= hb <- hexbin(NHANES$Transferin, NHANES$Hemoglobin, shape = shape) hbhp <- hboxplot(erode(hb,cdfcut = .05),unzoom = 1.3) pushHexport(hbhp,clip = 'on') hexGraphPaper(hb,fill.edges = 3) popViewport() @ \caption{Hexagon "boxplots" showing the top 95 percent of the data for males and females. The red hexagons are an estimate of the bivariate median.} \label{hbox} \end{figure} Note that we have added ``hexagon graph paper'' to the plot. This can be done for any hexbin plot, using the command \texttt{hexGraphPaper()} where the main argument is the hexbin object. \subsection{Comparing Distributions and the \texttt{hdiffplot}} With univariate data, if there are multiple groups, one often uses a density estimate to overlay densities, and compare two or more distributions. The hdiffplot is the bivariate analog. The idea behind the hdiff plot is to plot one or more bin objects representing multiple groups to compare the distributions. The following example uses the National Health data supplied in the hexbin package, (\texttt{NHANES}). Below we show a comparison of males and females, the bivariate relationship is transferin, which is a derived measure of the ability of blood to bind oxygen, vs the level of hemoglobin. Note that in the call to \texttt{hdiffplot} we erode the bins to calculate the bivariate medians, and only display the upper 75\% of the data. \begin{figure}[h] \centering << hdiff, fig = TRUE, width = 6, height = 4, echo = TRUE >>= #grid.newpage() shape <- optShape(height = vpin[2],width = vpin[1],mar = mai) xbnds <- range(NHANES$Transferin,na.rm = TRUE) ybnds <- range(NHANES$Hemoglobin,na.rm = TRUE) hbF <- hexbin(NHANES$Transferin[NHANES$Sex == "F"], NHANES$Hemoglobin[NHANES$Sex == "F"], xbnds = xbnds, ybnds = ybnds, shape = shape) hbM <- hexbin(NHANES$Transferin[NHANES$Sex == "M"], NHANES$Hemoglobin[NHANES$Sex == "M"], xbnds = xbnds, ybnds = ybnds, shape = shape) #plot.new() hdiffplot(erode(hbF,cdfcut = .25),erode(hbM,cdfcut = .25),unzoom = 1.3) @ \caption{A difference plot of transferin vs hemoglobin for males and females.} \label{hdiffplot} \end{figure} \subsection{Plotting a Third Concomitant Variable} In many cases, such as with spatial data, one may want to plot the levels of a third variable in each hexagon. The grid.hexagons function has a pair of arguments, \texttt{use.count} and \texttt{cell.at}. If \texttt{use.count = FALSE} and \texttt{cell.at} is a numeric vector of the same length as \texttt{hexbin@count} then the attribute vector will be used instead of the counts. \texttt{hexTapply} will summarize values for each hexagon according to the supplied function and return the table in the right order to use as an attribute vector. Another alternative is to set the \texttt{cAtt} slot of the hexbin object and grid.hexagons will automatically plot the attribute if \texttt{use.count = FALSE} and \texttt{cell.at = NULL}. Here is an example using spatial data. Often cartographers use graduated symbols to display varying numerical quantities across a region. \section{Example: cDNA Chip Normalization} This example is taken from the marray package, which supplies methods and classes for the normalization and diagnostic plots of cDNA microarrays. In this example the goal is not to make any comments about the normalization methodology, but rather to show how the diagnostic plots can be enhanced using hexagon binning due to the large number of points ($n = 8,448$ cDNA probes per chip). We look at the diagnostic plot $M$ vs $A$, where $M$ is the log--ratio, $M = \log <- 2 \frac{R}{G}$ and $A$ is the overall intensity, $A = \log <- 2\sqrt{RG}$. Figure~3 shows the plot using points and on the right hexagons. The hexagon binned plot shows that most of the pairs are well below zero, and that the overall shape is more like a comet with most of the mass at the bottom of the curve, rather than a thick bar of points curving below the line. << marray1, fig = TRUE, results = hide >>= ### Need to redo this part. library("marray") data(swirl, package = "marray") ## use swirl dataset hb1 <- hexbin(maA(swirl[,1]), maM(swirl[,1]), xbins = 40) grid.newpage() pushViewport(viewport(layout = grid.layout(1, 2))) pushViewport(viewport(layout.pos.col = 1,layout.pos.row = 1)) nb <- plot(hb1, type = 'n', xlab = 'A', ylab = 'M', main = "M vs A plot with points", legend = 0, newpage = FALSE) pushHexport(nb$plot.vp) grid.points(maA(swirl[,1]), maM(swirl[,1]),pch = 16,gp = gpar(cex = .4)) popViewport() nb$hbin <- hb1 hexVP.abline(nb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(nb) popViewport() pushViewport(viewport(layout.pos.col = 2,layout.pos.row = 1)) hb <- plotMAhex(swirl[,1], newpage = FALSE, main = "M vs A plot with hexagons", legend = 0) hexVP.abline(hb$plot.vp,h = 0,col = gray(.6)) hexMA.loess(hb) popViewport() @ \section{Manipulating Hexbins} The underlying functions for hexbin have been rewritten and now depend on the grid graphics system. The support unit for all hexagon plots is the hexViewport. The function \texttt{hexViewport()} takes a hexbin object as input and creates a viewport scaled to the current device or viewport so that the aspect ratio is scaled appropriately for the hexagons. Unlike in the base graphic functions where the aspect ratio is maintained by shifting the range of the axes, here the extra space is shifted into the margins. Currently hexViewport returns a hexViewport object that has information on the margins and its own pushViewport method. In the next example we will 1st show how to manipulate an existing plot using grid commands and second show how to create a custom plotting function using \texttt{hexViewport} and grid. \subsection{Adding to an existing plot} Adding to an existing plot requires the use of grid functions. For instance, in the following code, << addto,fig = TRUE,echo = TRUE >>= hplt <- plot(hb1,style = 'centroid',border = gray(.65)) pushHexport(hplt$plot.vp) ll.fit <- loess(hb1@ycm ~ hb1@xcm, weights = hb1@count, span = .4) pseq <- seq(hb1@xbnds[1]+1, hb1@xbnds[2]-1, length = 100) grid.lines(pseq, predict(ll.fit,pseq), gp = gpar(col = 2), default.units = "native") @ we have to use \texttt{grid.lines()}, as opposed to \texttt{lines()}. \end{document} hexbin/README.md0000644000175100001440000000030012542074613013021 0ustar hornikusershexbin ====== [![Build Status](https://travis-ci.org/edzer/hexbin.png?branch=master)](https://travis-ci.org/edzer/hexbin) An R Package with binning and plotting functions for hexagonal bins. hexbin/MD50000644000175100001440000000746012565120224012063 0ustar hornikusersb8c6e7f6b0230cdf61f0976d387c7a44 *ChangeLog 58f0420f8288b4faae52aba21669bc3d *DESCRIPTION 9129a733a21f780d50b1c3bb85da0047 *NAMESPACE 98a77d0235bb074f09aa7675358b8650 *R/BTC.R b8083617bec9ef2a20bf2fb31d1f50cb *R/BTY.R def8a3ae791d6214f8093069780971a3 *R/HO.R e54503901b17f4b00ab192bef093ff18 *R/LINGRAY.R 9220834650597d3f9a3c2f5a38fb2fc6 *R/LOCS.R 47006284b4bc42824409e49cd3ebb6e7 *R/MAG.R c25363a22b3f824d1f25997179b74434 *R/RB.R 97262cc9f616661bf71e4686225f6c17 *R/grid.hexagons.R cd88d10aa75a6666b296efff0ac1f355 *R/grid.hexlegend.R 503b110bf985d5c12a0d514c333dc81e *R/hbox.R ad4a901fb8fc48deb4f76ad3d797ecd9 *R/hdiffplot.R d53fcb4dabb71c0154e881648c6b13da *R/hexPlotMA.R e5cb8c5f3ba8f183d4c69e50f153f845 *R/hexViewport.R 48ab7518d22b3310dab41acae327c743 *R/hexbin.s4.R 5d66d35fa92d45957684ee3375513e28 *R/hexbinList.R ae5724baa7c3661621ed0018287fc6ca *R/hexbinplot.R 53e8c6ea014e06b21e56b8e447a0dad5 *R/hexpanel.R 249d47000fdc8b641cf6ed2ee6f640bb *R/hexplom.R 0b7181a5ae4cbc780f46041886fc80e8 *R/hexutil.R acf4489ea175f01eb1659a420183e155 *R/lattice.R 449d6bbfb6927f39383b586ffce19eb1 *R/smoothHexbin.R 408e6e0599f15c991715933ddd85400f *README.md 53e586900ba0c452c12ec7aed3d20295 *TODO dd1765c586720d0a4c7c5064fce7da74 *build/vignette.rds cfa9343134507d8eaf7386167ea1243d *data/NHANES.rda a6e0f6f67abc1c4d94ad6b2d33860fe2 *inst/doc/hexagon_binning.R ed9dbcabcbb9240445d6dac2de22ba5f *inst/doc/hexagon_binning.Rnw 4550e584d1ad491edcb547bd4ec28845 *inst/doc/hexagon_binning.pdf 3b3cb098160c79abc4d739397d315ff3 *man/NHANES.Rd bfc5169b22c653bb5912e9c3e92f3207 *man/colramp.Rd 94a1639600897389f489b6b836362d82 *man/erode.hexbin.Rd 47a11326b5056014da626fe8c3c5b8e8 *man/getHMedian.Rd 651ab732e881463b6516824c162e35ac *man/gplot.hexbin.Rd 4f14ff188dcc89ced1434511b0da5dc0 *man/grid.hexagons.Rd 6e12f30832b4d71515a91bb8c448049d *man/grid.hexlegend.Rd 5f2695c8af33d84b154a61e3463859e9 *man/hboxplot.Rd eb4f91c7c9c4482122d7c9ee209e93b6 *man/hcell2xy.Rd 9a215a3b0ff1077d865688a5d9a40921 *man/hcell2xyInt.Rd 29e7649124c53711586904d9c556f53e *man/hdiffplot.Rd f49d784dfab4e373b90f6399c511235f *man/hexGraphPaper.Rd cbc932856dc584b571a425fe4b7ec414 *man/hexList.Rd e674cd78f6a724d5613ddc81c6983b10 *man/hexMA.loess.Rd 15c9da95418b954cc0feeec69eff71cb *man/hexTapply.Rd 18c065f4f0c331f17604d467cf00b305 *man/hexVP-class.Rd 9c7707d15c10f959d35a0714dc65b667 *man/hexVP.abline.Rd 1f4b3a61121669b0bccb6fdc4e5cd836 *man/hexViewport.Rd 92c69549ef7b876c66bd362e17216c44 *man/hexbin.Rd 22b3b2d3c0f376d10a284f34eb647229 *man/hexbinplot.Rd 37d121666c32d6396a680761b201162d *man/hexplom.Rd 13241d553371e3923f6647b3a7deea77 *man/hexpolygon.Rd 85e71d3e73900af44b7e88ead81c033c *man/hsmooth-methods.Rd 7ea0b41a11cca81d2093012166c35101 *man/inout.hex.Rd fe9d76fede0a6c4727a6efb5c2e3c861 *man/list2hexList.Rd 087875e158137bd1494533ffc2078ebd *man/old-classes.Rd 6ed5394a980386786a41eaffd7dd5c8a *man/optShape.Rd 9f23953a55209099110283ec98343438 *man/panel.hexboxplot.Rd 3d36abbaab3ec18876e2288151da11f1 *man/panel.hexgrid.Rd d62970352d19f6785e76d6c68f3ba79e *man/panel.hexloess.Rd 9da0d7245fb3f734cc0f07cb4f2aa123 *man/plotMAhex.Rd fc017f52b40dc804a41ea45305c840d8 *man/pushHexport.Rd febf2f7e1ad56316da2058e260732d7a *man/smooth.hexbin.Rd 886e2efe62994815b8acfcc78c7ad81b *src/hbin.f 470ef863da306fb9d0955b3cdb0b2ce0 *src/hcell.f f8fb4b9ec5a1dbc174102d40377ce885 *src/herode.f 719cbe239d3f98da12bd7f489ab6c197 *src/hsm.f ddcf0653ed6863dd0260e1f58349356a *tests/hdiffplot.R 66fb0e8391d2b94fbdb2633ac4d70e21 *tests/hdiffplot.Rout.save efe67770786c28cc2bfceef357376f7a *tests/hray.R 24021c6251d46ad71065e3705e04479d *tests/hray.Rout.save 6dca74e0501c54cede56d657a1c0c632 *tests/large.R 98321f01b4ed346aa059aec1aa3c637a *tests/large.Rout.save f94ffad94528308a3483bf6f4088fa70 *tests/viewp-ex.R 53478aa4cafb6fb935b12b7c982a667d *tests/viewp-ex.Rout.save d6c9a9e05a1165a6e0da8b309303082b *vignettes/hexagon_binning.Rnw hexbin/build/0000755000175100001440000000000012371677051012655 5ustar hornikusershexbin/build/vignette.rds0000644000175100001440000000041312565116271015207 0ustar hornikusersJ0dV7n}C }@4O>bqb irF1 ڊflHߠi-*/CSn"dz"Be߀Eӟeق1 LH| ҅?߽ɛZ[ - ,-ڀ>v|+!X&h1ip359ټ&I#C"`Q5qFj1 ,\0hexbin/DESCRIPTION0000644000175100001440000000206512565120224013255 0ustar hornikusersPackage: hexbin Version: 1.27.1 Date: 2015-08-19 Title: Hexagonal Binning Routines Author: Dan Carr , ported by Nicholas Lewin-Koh and Martin Maechler , contains copies of lattice functions written by Deepayan Sarkar Maintainer: Edzer Pebesma Depends: R (>= 2.0.1), methods Imports: lattice, grid, graphics, grDevices, stats, utils Suggests: marray, affy, Biobase, limma Description: Binning and plotting functions for hexagonal bins. Now uses and relies on grid graphics and formal (S4) classes and methods. Collate: lattice.R BTC.R BTY.R grid.hexagons.R grid.hexlegend.R hbox.R hdiffplot.R hexbinList.R hexbinplot.R hexbin.s4.R hexpanel.R hexplom.R hexPlotMA.R hexutil.R hexViewport.R HO.R LINGRAY.R LOCS.R MAG.R RB.R smoothHexbin.R License: GPL-2 NeedsCompilation: yes URL: http://github.com/edzer/hexbin Packaged: 2015-08-19 15:11:53 UTC; edzer Repository: CRAN Date/Publication: 2015-08-19 17:28:20 hexbin/ChangeLog0000644000175100001440000000424111551510077013322 0ustar hornikusers2009-08-09 Nicholas Lewin-Koh * R/grid.hexagons.R removed break statements, switch fails. Cow lattice and centroid can ramp colors. Bug submitted by Ricardo DeLemos" * man/hexVP-class.Rd Shape slot was not documented 2009-02-26 Nicholas Lewin-Koh * R/grid.hexagons.R fixed bad if construct * R/hexbin.s4.R changed xlab and ylab signatures in class hexbin from character to vector, patch submitted by Don Armstrong 2008-04-28 Martin Maechler * DESCRIPTION (Version): 1.13.4 * man/*.Rd: fixes to several man pages; note that gplot.hexbin() now is *deprecated* ! 2008-03-18 Patrick Aboyoun * man/panel.hexboxplot, man/panel.hexgrid, man/panel.hexloess: Added more information to man files. * R/hexbinplot.R (panel.hexboxplot): removed unused singles argument. 2008-03-12 Patrick Aboyoun * R/hexViewport.R (hexVP.abline): Fixed the handling of non-model objects as input. 2008-02-28 Patrick Aboyoun * R/hexPlotMA.R (plotMAhex): Require users to specify status explicitly rather than as the component MA$genes$Status * R/hexPlotMA.R (plotMAhex): Replaced support of Biobase class exprSet with ExpressionSet 2006-09-28 Martin Maechler * NAMESPACE: add full list of colorspace dependencies 2005-07-26 Martin Maechler * R/hexViewport.R (smartBnds): some rationalization * R/hexViewport.R (rname): dito 2005-07-19 Martin Maechler * DESCRIPTION (Version): 1.3.1 (not to confuse with the previous one). * man/gplot.hexbin.Rd: fix typo and usage for S4method * R/hexPlotMA.R (hexMA.loess): add argument 'n' * R/hexViewport.R (hexVP.loess): add argument 'n'; other "white space cosmetic" in file 2005-10-21 Nicholas Lewin-Koh * added Deepayan Sarkar's hexbinplot.R function for lattice hexbin plots * Added my Hexplom function based on Deepayan's code 2005-10-27 Nicholas Lewin-Koh * Added more panel functions, for hexboxplots and hdiffplots. hexbin/man/0000755000175100001440000000000012371752042012323 5ustar hornikusershexbin/man/hexMA.loess.Rd0000644000175100001440000000234211551510077014740 0ustar hornikusers\name{hexMA.loess} \alias{hexVP.loess} \alias{hexMA.loess} \title{Add Loess Fit to Hexplot } \description{ Fit a loess line using the hexagon centers of mass as the x and y coordinates and the cell counts as weights. } \usage{ hexMA.loess(pMA, span = 0.4, col = "red", n = 200) hexVP.loess(hbin, hvp = NULL, span = 0.4, col = "red", n = 200) } \arguments{ \item{hbin}{an object of class \code{hexbin}, see \code{\link{hexbin}}.} \item{hvp}{A \code{hexViewport} object.} \item{pMA}{the list returned by \code{\link{plotMAhex}}.} \item{span}{the parameter alpha which controls the degree of smoothing.} \item{col}{line color for the loess fit.} \item{n}{number of points at which the fit should be evaluated.} } \value{ Returns invisibly the object associated with the loess fit. } \author{Nicholas Lewin-Koh } \seealso{ \code{\link{hexVP.abline}}, \code{\link{plotMAhex}}, \code{\link{gplot.hexbin}}, \code{\link{hexViewport}}; \code{\link{loess}} } \examples{ if(require(marray)){ data(swirl) %% the following had 'newpage = FALSE, ' -- why ?? hb <- plotMAhex(swirl[,1], main = "M vs A plot with hexagons", legend=0) hexVP.abline(hb$plot, h=0, col= gray(.6)) hexMA.loess(hb) } } \keyword{aplot} hexbin/man/hexVP.abline.Rd0000644000175100001440000000303612102122233015060 0ustar hornikusers\name{hexVP.abline} \alias{hexVP.abline} \title{Add a Straight Line to a HexPlot} \description{ This function adds one or more straight lines through the current plot; it is the hexbin version of \code{\link[graphics]{abline}()}. } \usage{ hexVP.abline(hvp, a = NULL, b = NULL, h = numeric(0), v = numeric(0), col = "black", lty = 1, lwd = 2, \dots) } \arguments{ \item{hvp}{A hexViewport object that is currently on the active device} \item{a,b}{the intercept and slope or if \code{b} is \code{NULL}, an \code{lm} object or a vector of length 2 with \code{c(intercept,slope)}} \item{h}{the y-value for a horizontal line.} \item{v}{the x-value for a vertical line.} \item{col, lty, lwd}{line color, type and width.} \item{\dots}{further graphical parameters.} } \details{ The first form specifies the line in intercept/slope form (alternatively \code{a} can be specified on its own and is taken to contain the slope and intercept in vector form). The \code{h=} and \code{v=} forms draw horizontal and vertical lines at the specified coordinates. The \code{coef} form specifies the line by a vector containing the slope and intercept. \code{lm} is a regression object which contains \code{reg$coef}. If it is of length 1 then the value is taken to be the slope of a line through the origin, otherwise, the first 2 values are taken to be the intercept and slope. } \author{Nicholas Lewin-Koh} \seealso{\code{\link{gplot.hexbin}}, \code{\link{hexViewport}}, \code{\link{hexMA.loess}} } \keyword{aplot} hexbin/man/panel.hexloess.Rd0000644000175100001440000000277612102123156015544 0ustar hornikusers\name{panel.hexloess} \alias{panel.hexloess} \title{Loess line for hexbin lattice plot} \description{ A panel function to add a loess line to a hexbin lattice plot. This function contravened CRAN policy and is no longer available. } \usage{ panel.hexloess(bin, w = NULL, span = 2/3, degree = 1, family = c("symmetric", "gaussian"), evaluation = 50, lwd = add.line$lwd, lty = add.line$lty, col, col.line = add.line$col, \dots) } \arguments{ \item{bin}{an object of class \code{hexbin}.} \item{w}{optional counts for object \code{bin}.} \item{span}{smoothness parameter for \code{loess}.} \item{degree}{degree of local polynomial used.} \item{family}{if \code{"gaussian"} fitting is by least-squares, and if \code{"symmetric"} a re-descending M-estimator is used.} \item{evaluation}{number of points at which to evaluate the smooth curve.} \item{lwd}{line weight graphical parameter.} \item{lty}{line type graphical parameter.} \item{col}{same as \code{col.line}.} \item{col.line}{line color graphical parameter.} \item{\dots}{optional arguments to \code{\link[stats]{loess.control}}.} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{ \code{\link{hexbinplot}}, \code{\link{panel.hexgrid}}, \code{\link{loess.smooth}}, \code{\link{loess.control}}, \code{\link[lattice:panel.functions]{panel.loess}} } \keyword{hplot} hexbin/man/inout.hex.Rd0000644000175100001440000000132011551510077014526 0ustar hornikusers\name{inout.hex} \alias{inout.hex} \title{Check points for inclusion} \description{ Check which points are in hexagons with \code{count} <= mincnt. } \usage{ inout.hex(hbin, mincnt) } \arguments{ \item{hbin}{an object of class \code{\link{hexbin}}.} \item{mincnt}{Cutoff, id's for counts less than mincnt are returned} } \details{ Check which points are in hexagons with \code{count} <= mincnt and returns the row ids for those points. One can use the ids to plot low ount hexagons as points instead. } \value{ A vector with the row ids of points which fall in hexagons with \code{count} less than or equal to mincnt } \author{Nicholas Lewin-Koh} \seealso{\code{\link{plotMAhex}}} \keyword{misc} hexbin/man/erode.hexbin.Rd0000644000175100001440000000522112371751620015165 0ustar hornikusers\name{erode.hexbin} \alias{erode} \alias{erode.hexbin} \alias{erode,hexbin-method} \alias{erodebin-class} \title{Erosion of a Hexagon Count Image} \description{ This erosion algorithm removes counts from hexagon cells at a rate proportional to the cells' exposed surface area. When a cell becomes empty, algorithm removes the emptied cell and notes the removal order. Cell removal increases the exposure of any neighboring cells. The last cell removed is a type of bivariate median. } \usage{ erode(hbin, cdfcut = 0.5) erode.hexbin(hbin, cdfcut = 0.5) } \arguments{ \item{hbin}{an object of class \code{\link{hexbin}}.} \item{cdfcut}{number in (0,1) indicating the confidence level for the limits.} } \value{ An \code{"erodebin"} object (with all the slots from \code{hbin}) and additionally with high count cells and a component \code{erode} that gives the erosion order. } \details{ The algorithm extracts high count cells with containing a given fraction (cdfcut) of the total counts. The algorithm extracts all cells if cdfcut=0. The algorithm performs gray-level erosion on the extracted cells. Each erosion cycle removes counts from cells. The counts removed for each cell are a multiple of the cell's exposed-face count. The algorithm choses the multiple so at least one cell will be empty or have a count deficit on each erosion cycle. The erode vector contain an erosion number for each cell. The value of erode is 6*erosion\_cycle\_ at\_ cell\_ removal - cell\_deficit\_at\_removal Cells with low values are eroded first. The cell with the highest erosion number is a candidate bivariate median. A few ties in erode are common. } \seealso{ \code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{hcell2xy}}, %%FIXME\code{\link{hcell}}, %% \code{\link{hboxplot}}, \code{\link{hdiffplot}}, %% \code{\link{hmatplot}}, \code{\link{gplot.hexbin}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}} } \examples{ set.seed(153) x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) smbin <- smooth.hexbin(bin) erodebin <- erode.hexbin(smbin, cdfcut=.5) plot(erodebin) ## bivariate boxplot hboxplot(erodebin, main = "hboxplot(erodebin)") %% MM: This looks wrong -- both the graphic and the logic in "par" here : # show erosion order plot(bin,style= "lat", minarea=1, maxarea=1, legend=FALSE, border=gray(.7)) %% FIXME: {compare with example in "hexbin0"} grid.hexagons(erodebin,style= "lat", minarea=1, maxarea=1,pen="green") xy <- hcell2xy(erodebin) library("grid") grid.text(lab = as.character(erodebin@erode), xy$x, xy$y, gp = gpar(col="white", cex=0.65)) } \keyword{hplot} hexbin/man/panel.hexboxplot.Rd0000644000175100001440000000401311551510077016101 0ustar hornikusers\name{panel.hexboxplot} \alias{panel.hexboxplot} \title{Boxplot for hexbin lattice plot} \description{ A panel function to add a boxplot to a hexbin lattice plot. } \usage{ panel.hexboxplot(x, y, xbins = 30, xbnds = c("data", "panel"), ybnds = c("data", "panel"), .prelim = FALSE, .cpl = current.panel.limits(), .xlim = .cpl$xlim, .ylim = .cpl$ylim, .aspect.ratio, type = character(0), cdfcut = 0.25, shadow = 0.05, ..., check.erosion = TRUE) } \arguments{ \item{x, y}{numeric vector or factor.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{.prelim, .cpl, .xlim, .ylim, .aspect.ratio}{for internal use.} \item{type}{character vector controlling additional augmentation of the display. A \code{"g"} in \code{type} adds a reference grid, an \code{"hg"} adds a hexagonal grid.} \item{cdfcut}{number in (0,1) indicating the confidence level for the erosion limits. See \code{\link{erode.hexbin}} for more information.} \item{shadow}{number in (0,1) indicating the confidence level for the erosion limits of a boxplot shadow. See \code{\link{erode.hexbin}} for more information.} \item{\dots}{potential further arguments passed on.} \item{check.erosion}{logical indicating only eroded points should be used for \code{"erodebin"} objects; simply passed to \code{\link{hcell2xy}}, see its documentation.} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{\code{\link{hexbinplot}}, \code{\link{panel.hexgrid}}, \code{\link[lattice]{panel.bwplot}} } \examples{ mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)), y = rep(1:2, 5000)) hexbinplot(y ~ x, mixdata, panel = panel.hexboxplot) } \keyword{hplot} hexbin/man/hexGraphPaper.Rd0000644000175100001440000000465211551510077015356 0ustar hornikusers\name{hexGraphPaper} \alias{hexGraphPaper} \alias{hgridcent} \title{Create a Hexgon Grid} \description{ Creates a hexagon grid that can be added to a plot created with grid graphics. } \usage{ hexGraphPaper(hb, xbnds = NULL, ybnds = NULL, xbins = 30, shape = 1, add = TRUE, fill.edges = 1, fill = 0, border = 1) hgridcent(xbins, xbnds, ybnds, shape, edge.add = 0) } \arguments{ \item{hb}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} \item{add}{a logical value indicating whether or not to add the grid to the current plot.} \item{fill.edges}{integer number of hexagons to add around the border} \item{fill}{the fill color for the hexagons} \item{border}{the color of the border of the hexagons} \item{edge.add}{offset (typically \code{fill.edges} above) used in \code{hgridcent}.} } \details{ If a hexbin object is given then the parameters xbins and shape are ignored. Different bounds can still be specified. The \code{fill.edges} parameter should be an integer. \code{fill.edges} takes the current grid and adds a layer of hexagons around the grid for each level of fill. So for example if \code{fill.edges= 2} than the dimensions of the grid would be \code{(i,j)+4}. \code{hgridcent()} is the utility function computing the resulting list (see section \dQuote{Value}). \strong{WARNING! If using a hexVP be sure to set clip to "on", otherwise the hexagon grid will bleed over the plot edges.} } \value{ Invisibly returns a list with th following components \item{x}{The x coordinates of the grid} \item{y}{the y coordinates of the grid} \item{dimen}{a vector of length 2 gining the rows and columns of the grid} \item{dx}{the horizontal diameter of the hexagons} \item{dy}{the vertical diameter of the hexagons} } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hcell2xy}}, \code{\link{hexpolygon}}, \code{\link{grid.hexagons}}} \examples{ x <- rnorm(10000) y <- rnorm(10000,x,x) hbin <- hexbin(x,y) hvp <- plot(hbin,type="n") pushHexport(hvp$plot,clip="on") hexGraphPaper(hbin,border=grey(.8)) grid.hexagons(hbin) } \keyword{aplot} \keyword{dplot} hexbin/man/old-classes.Rd0000644000175100001440000000127711551510077015031 0ustar hornikusers\name{old-classes} \title{Class "unit" and "viewport" as S4 classes} % \docType{class} \alias{unit-class} \alias{viewport-class} % \description{Package "hexbin" now uses S4 classes throughout and hence needs to \code{\link[methods]{setOldClass}} both \code{"unit"} and \code{"viewport"} (which are S3 classes from the \pkg{grid} package), in order to be able to use those in slots of its own classes. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Extends}{ Class \code{"oldClass"}, directly. } \section{Methods}{ No methods defined with class "unit" in the signature. } % \seealso{ % add link to grid ?? % } \keyword{classes} hexbin/man/smooth.hexbin.Rd0000644000175100001440000000611411551510077015400 0ustar hornikusers\name{smooth.hexbin} \alias{smooth.hexbin} \alias{smoothbin-class} \title{Hexagon Bin Smoothing} \description{ Given a \code{"hexbin"} (hexagon bin) object, compute a discrete kernel smoother that covers seven cells, namely a center cell and its six neighbors. With two iterations the kernel effectively covers 1+6+12=19 cells. } \usage{ smooth.hexbin(bin, wts=c(48,4,1)) } \arguments{ \item{bin}{object of class \code{"hexbin"}, typically resulting from \code{\link{hexbin}()} or \code{\link{erode,hexbin-method}}.} \item{wts}{numeric vector of length 3 for relative weights of the center, the six neighbor cells, and twelve second neighbors.} } \value{ an object of class \code{"smoothbin"}, extending class \code{"hexbin"}, see \code{\link{hexbin}}. The object includes the additional slot \code{wts}. } \references{see \code{\link{grid.hexagons}} and \code{\link{hexbin}}.} \details{ This discrete kernel smoother uses the center cell, immediate neighbors and second neighbors to smooth the counts. The counts for each resulting cell is a linear combination of previous cell counts and weights. The weights are \tabular{ll}{ 1 center cell, \tab weight = wts[1]\cr 6 immediate neighbors\tab weight = wts[2]\cr 12 second neighbors \tab weight =wts[3]\cr } If a cell, its immediate and second neighbors all have a value of \code{max(cnt)}, the new maximum count would be \code{max(cnt)*sum(wts)}. It is possible for the counts to overflow. The domain for cells with positive counts increases. The hexbin slots \code{xbins}, \code{xbnds}, \code{ybnds}, and \code{dimen} all reflect this increase. Note that usually \code{dimen[2] = xbins+1}. The intent was to provide a fast, iterated, immediate neighbor smoother. However, the current hexbin plotting routines only support shifting even numbered rows to the right. Future work can (1) add a shift indicator to hexbin objects that indicates left or right shifting.\cr (2) generalize plot.hexbin() and hexagons()\cr (3) provide an iterated kernel.\cr With \code{wts[3]=0}, the smoother only uses the immediate neighbors. With a shift indicator the domain could increase by 2 rows (one bottom and on top) and 2 columns (one left and one right). However the current implementation increases the domain by 4 rows and 4 columns, thus reducing plotting resolution. } \seealso{ \code{\link{hexbin}}, \code{\link{erode.hexbin}}, %MISSING \code{\link{hthin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, %\code{\link{hdiffplot}}, \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \examples{ x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) # show the smooth counts in gray level smbin <- smooth.hexbin(bin) plot(smbin, main = "smooth.hexbin(.)") # Compare the smooth and the origin smbin1 <- smbin smbin1@count <- as.integer(ceiling(smbin@count/sum(smbin@wts))) plot(smbin1) smbin2 <- smooth.hexbin(bin,wts=c(1,0,0)) # expand the domain for comparability plot(smbin2) } \keyword{misc} hexbin/man/hexViewport.Rd0000644000175100001440000000355512371427310015143 0ustar hornikusers\name{hexViewport} \alias{hexViewport} \title{Compute a Grid Viewport for Hexagon / Hexbin Graphics} \description{ Builds a \code{grid} viewport for hexagon or \code{\link{hexbin}} graphics. This builds on the concepts of the \pkg{grid} package, see \code{\link[grid]{viewport}}. } \usage{% see ../R/hexViewport.R hexViewport(x, offset = unit(0,"inches"), mar = NULL, xbnds = NULL, ybnds = NULL, newpage = FALSE, clip = "off", vp.name = NULL) } \arguments{ \item{x}{a \code{\link{hexbin}} object.} \item{offset}{a \code{\link[grid]{unit}} object.} \item{mar}{margins as \code{\link[grid]{unit}}s, of length 4 or 1.} \item{xbnds, ybnds}{bounds for x- and y- plotting range; these default to the corresponding slots of \code{x}.} \item{newpage}{logical indicating if a new graphics page should be openend, i.e., \code{\link[grid]{grid.newpage}()}.} \item{clip}{simply passed to \code{\link[grid]{viewport}()}.} \item{vp.name}{name of viewport; defaults to random name.} } \value{ an S4 object of class \code{"hexVP"}, see \link{hexVP-class} for more, with its main slot \code{hexVp} a \code{\link[grid]{viewport}} for grid graphics. } \seealso{\code{\link[grid]{viewport}} and the main \emph{\dQuote{handlers}} \code{\link{pushHexport}} and \code{\link[grid:viewports]{popViewport}}; further \code{\link{gplot.hexbin}} and \code{\link{hboxplot}} which build on \code{hexViewport}. } \examples{ set.seed(131) x <- rnorm(7777) y <- rt (7777, df=3) ## lower resolution binning and overplotting with counts bin <- hexbin(x,y,xbins=25) P <- plot(bin) xy <- hcell2xy(bin) pushHexport(P$plot.vp) i <- bin@count <= 3 library("grid") grid.text(as.character(bin@count[i]), xy$x[i], xy$y[i], default.units = "native") grid.points(x[1:20],y[1:20]) # to show some points rather than counts popViewport() } \keyword{hplot}% ? \keyword{aplot} hexbin/man/getHMedian.Rd0000644000175100001440000000134511551510077014621 0ustar hornikusers\name{getHMedian} \alias{getHMedian} \alias{getHMedian,erodebin-method} \title{Get coordiantes of the median cell after the erode operation} \description{ A method for a eroded hexbin object to extract the coordinates of the median cell. The median is simply the cell with the highest erosion number or the last cell to be eroded. } \usage{ getHMedian(ebin) } \arguments{ \item{ebin}{result of \code{\link{erode.hexbin}()}.} } \section{Methods}{ \describe{ \item{ebin = "erodebin"}{...} } } \seealso{\code{\link{erode.hexbin}} } \examples{ set.seed(153) x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) smbin <- smooth.hexbin(bin) erodebin <- erode.hexbin(smbin, cdfcut=.5) getHMedian(erodebin) } \keyword{methods} hexbin/man/pushHexport.Rd0000644000175100001440000000161011551510077015140 0ustar hornikusers\name{pushHexport} \alias{pushHexport} \title{Push a Hexagon Viewport ("hexVP")} \description{ Push a Hexagon Viewport (\code{"hexVP"}, see \link{hexVP-class}) on to the tree of (grid) viewports, calling \code{\link[grid:viewports]{pushViewport}}. } \usage{ pushHexport(hvp, clip = "off") } \arguments{ \item{hvp}{a hexagon viewport, i.e., an object of class \code{"hexVP"}, see \link{hexVP-class}, typically produced by \code{\link{hexViewport}(..)}.} \item{clip}{which viewport to push, either 'on' or 'off' are the allowed arguments, see details.} } \seealso{the underlying \code{\link[grid:viewports]{pushViewport}} from the \pkg{grid} package. } \details{ A hexagon viewport (\code{"hexVP"}) object has slots for two replicate viewports one with clipping turned on and one with clipping off. This allows toggling the clipping option. } %\examples{ %} \keyword{dplot} hexbin/man/hexbin.Rd0000644000175100001440000000776611551510077014106 0ustar hornikusers\name{hexbin} \title{Bivariate Binning into Hexagon Cells} \alias{hexbin} \alias{hexbin-class} \alias{integer or NULL-class} \alias{show,hexbin-method} \alias{summary,hexbin-method} \description{ Creates a \code{"hexbin"} object. Basic components are a cell id and a count of points falling in each occupied cell. Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin}) and \code{\link{summary}()}, but also \code{\link{erode}}. % .. \code{\link{smooth.hexbin}} } \usage{ hexbin(x, y, xbins = 30, shape = 1, xbnds = range(x), ybnds = range(y), xlab = NULL, ylab = NULL, IDs = FALSE) } \arguments{ \item{x, y}{vectors giving the coordinates of the bivariate data points to be binned. Alternatively a single plotting structure can be specified: see \code{\link[grDevices]{xy.coords}}. \code{\link{NA}}'s are allowed and silently omitted.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{xlab, ylab}{optional character strings used as labels for \code{x} and \code{y}. If \code{NULL}, sensible defaults are used.} \item{IDs}{logical indicating if the individual cell \dQuote{IDs} should be returned, see also below.} } \value{ an S4 object of class \code{"hexbin"}. It has the following slots: \item{cell}{vector of cell ids that can be mapped into the (x,y) bin centers in data units.} \item{count}{vector of counts in the cells.} \item{xcm}{The x center of mass (average of x values) for the cell.} \item{ycm}{The y center of mass (average of y values) for the cell.} \item{xbins}{ number of hexagons across the x axis. hexagon inner diameter =diff(xbnds)/xbins in x units} \item{shape}{plot shape which is yheight(inches) / xwidth(inches)} \item{xbnds}{x coordinate bounds for binning and plotting} \item{ybnds}{y coordinate bounds for binning and plotting} \item{dimen}{The i and j limits of cnt treated as a matrix cnt[i,j]} \item{n}{number of (non NA) (x,y) points, i.e., \code{sum(* @count)}.} \item{ncells}{number of cells, i.e., \code{length(* @count)}, etc} \item{call}{the function call.} \item{xlab, ylab}{character strings to be used as axis labels.} \item{cID}{of class, \code{"integer or NULL"}, only if \code{IDs} was true, an integer vector of length \code{n} where \code{cID[i]} is the cell number of the i-th original point \code{(x[i], y[i])}. Consequently, the \code{cell} and \code{count} slots are the same as the \code{\link{names}} and entries of \code{table(cID)}, see the example.} } \seealso{ \code{\link{hcell2xy}}%, \code{\link{hcell}}, % FIXME \code{\link{gplot.hexbin}},% \code{\link{hboxplot}}, % \code{\link{hdiffplot}}, \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \references{ Carr, D. B. et al. (1987) Scatterplot Matrix Techniques for Large \eqn{N}. \emph{JASA} \bold{83}, 398, 424--436. } \details{ Returns counts for non-empty cells only. The plot shape must be maintained for hexagons to appear with equal sides. Some calculations are in single precision. Note that when plotting a \code{hexbin} object, the \pkg{grid} package is used. You must use its graphics (or those from package \pkg{lattice} if you know how) to add to such plots. } \examples{ set.seed(101) x <- rnorm(10000) y <- rnorm(10000) (bin <- hexbin(x, y)) ## or plot(hexbin(x, y + x*(x+1)/4), main = "(X, X(X+1)/4 + Y) where X,Y ~ rnorm(10000)") ## Using plot method for hexbin objects: plot(bin, style = "nested.lattice") hbi <- hexbin(y ~ x, xbins = 80, IDs= TRUE) str(hbi) tI <- table(hbi@cID) stopifnot(names(tI) == hbi@cell, tI == hbi@count) ## NA's now work too: x[runif(6, 0, length(x))] <- NA y[runif(7, 0, length(y))] <- NA hbN <- hexbin(x,y) summary(hbN) } \keyword{dplot} hexbin/man/hexplom.Rd0000644000175100001440000000570411551510077014273 0ustar hornikusers\name{hexplom} \title{Hexbin Plot Matrices} \alias{hexplom} \alias{hexplom.formula} \alias{hexplom.data.frame} \alias{hexplom.matrix} \alias{panel.hexplom} \usage{ hexplom(x, data, \dots) \method{hexplom}{formula}(x, data = NULL, \dots) \method{hexplom}{data.frame}(x, data = NULL, \dots, groups = NULL, subset = TRUE) \method{hexplom}{matrix}(x, data = NULL, \dots, groups = NULL, subset = TRUE) panel.hexplom(\dots) } \description{ \code{hexplom} draws Conditional Hexbin Plot Matrices. It is similar to \code{splom}, expect that the default display is different. Specifically, the default display is created using \code{panel.hexplom}, which is an alias for \code{panel.hexbinplot}. } \arguments{ \item{x}{ The object on which method dispatch is carried out. For the \code{"formula"} method, a formula describing the structure of the plot, which should be of the form \code{~ x | g1 * g2 * \dots}, where \code{x} is a data frame or matrix. Each of \code{g1, g2, \dots} must be either factors or shingles. The conditioning variables \code{g1, g2, \dots} may be omitted. For the \code{data.frame} and \code{matrix} methods, a data frame or matrix as appropriate. } \item{data}{ For the \code{formula} method, an optional data frame in which variables in the formula (as well as \code{groups} and \code{subset}, if any) are to be evaluated. By default, the environment where the function was called from is used. } \item{groups, subset, \dots}{ see \code{\link[lattice]{splom}}. The non-standard evaluation of \code{groups} and \code{subset} only applies in the \code{formula} method. Apart from arguments that apply to \code{splom} (many of which are only documented in \code{\link[lattice]{xyplot}}), additional arguments meant for \code{panel.hexplom} (which is an alias for \code{\link{panel.hexbinplot}}) may also be supplied. Such arguments may include ones that control details of the hexbin calculations, documented in \code{\link{gplot.hexbin}}} } \value{ An object of class \code{"trellis"}. The \code{\link[lattice:update.trellis]{update}} method can be used to update components of the object and the \code{\link[lattice:print.trellis]{print}} method (usually called by default) will plot it on an appropriate plotting device. } \seealso{ \code{\link[lattice]{splom}}, \code{\link[lattice]{xyplot}}, \code{\link[hexbin]{hexbinplot}}, \code{\link[lattice]{Lattice}}, \code{\link[lattice]{panel.pairs}} } \author{ Deepayan Sarkar \email{Deepayan.Sarkar@R-project.org}, Nicholas Lewin-Koh \email{nikko@hailmail.net}} \examples{ ## Simple hexplom data(NHANES) hexplom(~NHANES[,7:14], xbins=15) ## With colors and conditioning hexplom(~NHANES[,9:13] | Sex, data = NHANES, xbins = 15, colramp = magent) ## With custom panel function hexplom(NHANES[,9:13], xbins = 20,colramp = BTY, upper.panel = panel.hexboxplot) } \keyword{hplot} hexbin/man/optShape.Rd0000644000175100001440000000317012371432054014374 0ustar hornikusers\name{optShape} \alias{optShape} %- Also NEED an '\alias' for EACH other topic documented here. \title{Optimal Shape Parameter for Hexbin Viewport} \description{ Takes a viewport or a given height and width and returns the shape parameter that will fill the specified plotting region with the appropriately shaped hexagons. If margins are specified the margins are subtracted from height and width before the shape parameter is specified. } \usage{ optShape(vp, height = NULL, width = NULL, mar = NULL) } \arguments{ \item{vp}{a \code{viewport} object, optional see details} \item{height}{the height of the plotting region, can be numeric or units} \item{width}{The width of the plotting region, can be numeric or units} \item{mar}{A four element numeric or units vector describing the margins in the order \code{c(bottom, left, top, right)}} } \value{ a scalar numeric value specifiyng \code{shape}. } \author{Nicholas Lewin-Koh} \section{Warning}{If a viewport is given as an argument it should already be pushed on the graphics device or it will have null units and a meaningless shape parameter will be returned. } \seealso{\code{\link{hexViewport}}, \code{\link{hexVP-class}}, \code{\link{hexbin}}} \examples{ x <- rgamma(10000,.9) m <- as.logical(rbinom(10000,1,.17)) x[m] <- -x[m] y <- rnorm(x,abs(x)) library("grid") vp <- plotViewport(xscale= range(x)+c(-.5,.5), yscale= range(y)+c(-.5,.5), default.units = "native") grid.newpage() pushViewport(vp) grid.rect() shape <- optShape(vp) shape hb <- hexbin(x,y,xbins=40,shape=shape) grid.hexagons(hb,colramp=BTY) } \keyword{dplot} hexbin/man/plotMAhex.Rd0000644000175100001440000001456111551510077014521 0ustar hornikusers\name{plotMAhex} \alias{plotMAhex} \title{MA-plot using hexagon bins} \description{ Creates an MA-plot using hexagons with color/glyph coding for control spots. } \usage{ plotMAhex(MA, array = 1, xlab = "A", ylab = "M", main = colnames(MA)[array], xlim = NULL, ylim = NULL, status = NULL, values, pch, col, cex, nbin = 40, zero.weights = FALSE, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 2, maxcnt = NULL, trans = NULL, inv = NULL, colorcut = NULL, border = NULL, density = NULL, pen = NULL, colramp = function(n) { LinGray(n, beg = 90, end = 15) }, newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), verbose = getOption("verbose")) } \arguments{ \item{MA}{an \code{RGList}, \code{MAList} or \code{MArrayLM} object, or any list with components \code{M} containing log-ratios and \code{A} containing average intensities. Alternatively a \code{matrix}, \code{Affybatch} or \code{ExpressionSet} object.} \item{array}{integer giving the array to be plotted. Corresponds to columns of \code{M} and \code{A}.} \item{xlab, ylab, main}{character strings giving label for x-axis, y-axis or main tile of the plot.} \item{xlim, ylim}{numeric vectors of length 2 giving limits for x-axis (or y-axis respectively), defaulting to min and max of the data.} \item{status}{character vector giving the control status of each spot on the array, of same length as the number of rows of \code{MA$M}. If omitted, all points are plotted in the default color, symbol and size.} \item{values}{character vector giving values of \code{status} to be highlighted on the plot. Defaults to unique values of \code{status}. Ignored if there is no \code{status} vector.} \item{pch}{vector or list of plotting characters. Default to integer code 16. Ignored is there is no \code{status} vector.} \item{col}{numeric or character vector of colors, of the same length as \code{values}. Defaults to \code{1:length(values)}. Ignored if there is no \code{status} vector.} \item{cex}{numeric vector of plot symbol expansions, of the the same length as \code{values}. Defaults to 0.2 for the most common status value and 1 for the others. Ignored if there is no \code{status} vector.} \item{nbin}{ Number of bins } %% << FIXME \item{zero.weights}{logical, should spots with zero or negative weights be plotted?} \item{style}{string specifying the style of hexagon plot, see \code{\link{grid.hexagons}} for the possibilities.} \item{legend}{numeric width of the legend in inches of \code{FALSE}. In the latter case, or when \code{0}, no legend is not produced.} \item{lcex}{characters expansion size for the text in the legend.} \item{minarea}{fraction of cell area for the lowest count.} \item{maxarea}{fraction of the cell area for the largest count.} \item{mincnt}{cells with fewer counts are ignored.} \item{maxcnt}{cells with more counts are ignored.} \item{trans}{\code{\link{function}} specifying a transformation for the counts such as \code{sqrt}.} \item{inv}{the inverse transformation of \code{trans}.} \item{colorcut}{vector of values covering [0, 1] that determine hexagon color class boundaries and hexagon legend size boundaries. Alternatively, an integer (\code{<= maxcnt}) specifying the \emph{number} of equispaced colorcut values in [0,1].} \item{border, density, pen}{color for polygon borders and filling of each hexagon drawn, passed to \code{\link{grid.hexagons}}.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{newpage}{should a new page start?} \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for suppressing the plotting of hexagon symbols, or the x- or y-axis, respectively.} \item{verbose}{logical indicating if some diagnostic output should happen.} } \details{ An MA-plot is a plot of log-intensity ratios (M-values) versus log-intensity averages (A-values). If \code{MA} is an \code{RGList} or \code{MAList} then this function produces an ordinary within-array MA-plot. If \code{MA} is an \code{MArrayLM} object, then the plot is an fitted model MA-plot in which the estimated coefficient is on the y-axis and the average A-value is on the x-axis. If \code{MA} is a \code{matrix} or \code{ExpressionSet} object, then this function produces a between-array MA-plot. In this case the A-values in the plot are the average log-intensities across the arrays and the M-values are the deviations of the log-intensities for the specified array from the average. If there are more than five arrays, then the average is computed robustly using medians. With five or fewer arrays, it is computed by means. The \code{status} vector is intended to specify the control status of each spot, for example "gene", "ratio control", "house keeping gene", "buffer" and so on. The vector is usually computed using the function \code{\link[limma]{controlStatus}} from package \pkg{limma} and a spot-types file. However the function may be used to highlight any subset of spots. The arguments \code{values}, \code{pch}, \code{col} and \code{cex} can be included as attributes to \code{status} instead of being passed as arguments to \code{plotMA}. See \code{\link[graphics]{points}} for possible values for \code{pch}, \code{col} and \code{cex}. } \value{ A plot is created on the current graphics device. and a list with the following items is returned invisibly: \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.} \item{legend.vp}{if a legend has been produced, its \code{\link[grid]{viewport}}.} \item{hbin}{a \code{hexbin} object built with A as the x coordinate and M as the y coordinate.} } \references{See \url{http://www.statsci.org/micrarra/refs/maplots.html}} \author{Nicholas Lewin-Koh, adapted from code by Gordon Smyth} \seealso{\code{\link[limma:plotma]{plotMA}} from package \pkg{limma}, and \code{\link{gplot.hexbin}}. } \examples{ if(require(marray)){ %% for the data only --> data(swirl, package="marray") data(swirl) hb <- plotMAhex(swirl[,1],newpage=FALSE, main = "M vs A plot with hexagons", legend=0) hexVP.abline(hb$plot.vp,h=0,col=gray(.6)) hexMA.loess(hb) } } \keyword{hplot} hexbin/man/hexTapply.Rd0000644000175100001440000000371011551510077014570 0ustar hornikusers\name{hexTapply} \alias{hexTapply} \title{Apply function to data from each hexagon bin.} \description{ A wrapper for tapply except that it operates with each hexagon bin being the category. The function operates on the data associated on the points from each bin. } \usage{ hexTapply(hbin, dat, FUN = sum, ..., simplify=TRUE) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{dat}{A vector of data the same length as \code{hbin@cID}} \item{FUN}{the function to be applied. In the case of functions like \code{+}, \code{\%*\%}, etc., the function name must be quoted. If \code{FUN} is \code{NULL}, tapply returns a vector which can be used to subscript the multi-way array \code{tapply} normally produces.} \item{\dots}{optional arguments to \code{FUN}.} \item{simplify}{If \code{FALSE}, \code{tapply} always returns an array of mode \code{"list"}. If \code{TRUE} (the default), then if \code{FUN} always returns a scalar, \code{tapply} returns an array with the mode of the scalar.} } \details{ This function is a wrapper for tapply, except that the cell id is always the categorical variable. This function is specifically good for adding variables to the cAtt slot of a hexbin object or for plotting a third variable in a hexagon plot. See below for examples. } \value{ Returns a vector of the result of 'FUN' as in \code{\link{tapply}}. See \code{\link{tapply}} for detailed description of output. } \author{Nicholas Lewin-Koh} \seealso{ \code{\link{tapply}},\code{\link{hexbin}} } \examples{ data(NHANES) hbin<-hexbin(log(NHANES$Diet.Iron+1),log(NHANES$BMI),xbins=25,IDs=TRUE) hvp<-plot(hbin) mtrans<-hexTapply(hbin,NHANES$Transferin,median,na.rm=TRUE) pushHexport(hvp$plot.vp) grid.hexagons(hbin,style='lattice',pen=0,border='red',use.count=FALSE, cell.at=mtrans) } \keyword{dplot} \keyword{utilities}% at least one, from doc/KEYWORDS hexbin/man/panel.hexgrid.Rd0000644000175100001440000000107312102122303015322 0ustar hornikusers\name{panel.hexgrid} \alias{panel.hexgrid} \title{Hexagonal grid for a lattice plot} \description{ A panel function to add a hexagonal grid to a lattice plot. } \usage{ panel.hexgrid(h, border = grey(0.85)) } \arguments{ \item{h}{an object of class \code{hexbin}.} \item{border}{a color for the hexagon border colors} } \value{ There is no return value from this function. The results are plotted on the current active device. } \author{Nicholas Lewin-Koh \email{nikko@hailmail.net}} \seealso{\code{\link{hexbinplot}}, \code{\link{hexGraphPaper}}} \keyword{hplot} hexbin/man/hcell2xy.Rd0000644000175100001440000000361011551510077014343 0ustar hornikusers\name{hcell2xy} \alias{hcell2xy} \alias{hcell2xy,hexbin-method} \title{Compute X and Y Coordinates for Hexagon Cells} \description{ Computes x and y coordinates from hexagon cell id's. } \usage{ hcell2xy(hbin, check.erosion = TRUE) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{check.erosion}{logical indicating if only the eroded points should be returned in the case where \code{hbin} inherits from \code{"erodebin"} (see \code{\link{erodebin-class}}); is \code{TRUE} by default.} } \value{ A list with two components of the same length as \code{bin$cell}, \item{x}{} \item{y}{} } %%FIXME \references{see in \code{\link{hcell}}.} \details{ The hexbin object \code{hbin} contains all the needed information. The purpose of this function is to reduce storage. The cost is additional calculation. } \seealso{%%FIXME \code{\link{hcell}}, \code{\link{hray}}, \code{\link{hexbin}}. } \examples{ x <- rnorm(10000) y <- rnorm(10000) plot(x,y, pch=".") hbin <- hexbin(x,y) str(xys <- hcell2xy(hbin)) points(xys, cex=1.5, col=2) ; title("hcell2xy( hexbin(..) )", col.main=2) %% __________ FIXME ________ \dontshow{ ## Temporal trends with confidence bounds plotted on a map: ## Illustration only pending access to user functions ## mtapply() # like tapply but for matrices ## sens.season.slope() # computes sen's seasonal slope ## This part does not work and commented out #hbin <- hcell(dat$x,dat$y) # x and y are in map projection units #newdat < dat[,c('month','year','value')] # extract columns #stats <- mtapply(newdat,bin$cell,sens.season.slope,season=12) #plot(mymap,type='l') # map boundaries in map projection units #xy <- hcell2xy(hbin) # x and y coordinates for hexagon cell centers #hray(xy$x, xy$y,val=stat[,1],lower= stat[,2],upper=stat[,3]) } } \keyword{manip} hexbin/man/hboxplot.Rd0000644000175100001440000000660212371426704014460 0ustar hornikusers\name{hboxplot} \alias{hboxplot} \title{2-D Generalization of Boxplot} \description{ If \code{bin} is an \emph{eroded} \code{\link{hexbin}} object, i.e., an \code{erodebin} object, \code{hboxplot()} plots the high counts cells selected by \code{\link{erode}()}. By default, the high counts cells contain 50 percent of the counts so analagous to the interquartile \dQuote{range}. The function distinguishes the last cells eroded using color. These cells correspond to one definition of the bivariate median. %% FIXME ^^ (bad style, content +- ok) } \usage{ hboxplot(bin, xbnds = NULL, ybnds = NULL, density, border = c(0, grey(0.7)), pen = c(2, 3), unzoom = 1.1, clip ="off", reshape = FALSE, xlab = NULL, ylab = NULL, main = "") } \arguments{ \item{bin}{an object of class \code{\link{hexbin}}.} \item{xbnds,ybnds}{global x- and y-axis plotting limits for multiple plots.} \item{density, border}{arguments for \code{\link{polygon}()} each of length two, the first for the median, the second for the other cells.} \item{pen}{colors (\dQuote{pen numbers}) for \code{polygon()}.} \item{unzoom}{plot limit expansion factor when \code{xbnds} is missing.} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{reshape}{logical value to reshape the plot although \code{xbnds} and \code{ybnds} are present.} \item{xlab, ylab, main}{x- and y- axis labels and main title} } \value{ invisibly, the \code{\link{hexViewport}()} used internally. Used to add to the plot afterwards. } \references{ see in \code{\link{grid.hexagons}}.} \details{ The \code{density}, \code{border}, and \code{pen} arguments correspond to the \code{\link{polygon}} function calls for plotting two types of cells. The cell types, pen numbers and suggested colors are\cr \tabular{lll}{ TYPE \tab PEN \tab COLOR \cr cells of bin \tab 2 \tab light gray \cr last eroded cells of bin (median cells)\tab 1 \tab black \cr } The erode components of the hexbin objects must be present for the medians cells to plot. When \code{xbnds} is missing or \code{reshape} is true, the plot changes graphics parameters and resets them. When \code{xbnds} is missing the function also zooms in based on the available data to provide increased resolution. The zoom used the hexagon cell centers. The unzoom argument backs off a bit so the whole hexagon will fit in the plot. \code{Hboxplot()} is used as a stand alone function, for producing separate legends .....%%FIXME for \code{\link{hmatplot}()} and for panels in %% \code{\link{hmatplot}()}. } \seealso{ \code{\link{hexbin}}, \code{\link{erode}}, %\code{\link{smooth.hexbin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, % \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}} } \examples{ \dontshow{set.seed(753)} ## boxplot of smoothed counts x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) erodebin <- erode(smooth.hexbin(bin)) hboxplot(erodebin) hboxplot(erodebin, density = c(32,7), border = c(2,4)) hp <- hboxplot(erodebin, density = c(-1,17), main = "hboxplot(erode*(smooth*(.)))") pushHexport(hp) library("grid") grid.points(x[1:10], y[1:10])# just non-sense to show the principle popViewport() } \keyword{hplot} hexbin/man/hsmooth-methods.Rd0000644000175100001440000000146411551510077015740 0ustar hornikusers\name{hsmooth-methods} \docType{methods}% + generic -- still use this doctype ? \alias{hsmooth}% generic \alias{hsmooth-methods} \alias{hsmooth,hexbin-method} \title{Hexagon Bin Smoothing: Generic hsmooth() and Methods} \description{ Methods for the generic function \code{hsmooth} in package \pkg{hexbin}: There is currently only the one for \code{\link{hexbin}} objects. } \usage{ \S4method{hsmooth}{hexbin}(bin, wts) } \arguments{ \item{bin}{a \code{\link{hexbin}} object, or an extension such as \code{\link{erodebin-class}}.} \item{wts}{weights vector, see \code{\link{smooth.hexbin}}} } \section{Methods}{ \describe{ \item{bin = "hexbin"}{is just the \code{\link{smooth.hexbin}} function (for back compatibility); see its documentation, also for examples.} } } \keyword{methods} hexbin/man/grid.hexlegend.Rd0000644000175100001440000000605711551510077015510 0ustar hornikusers\name{grid.hexlegend} \alias{grid.hexlegend} \title{Add a Legend to a Hexbin Plot} \description{ Plots the legend for the \code{plot} method of \code{\link{hexbin}}. Provides a legend indicating the count representations. } \usage{ grid.hexlegend(legend, ysize, lcex, inner, style = , minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut, density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, leg.unit = "native") } \arguments{ \item{legend}{positive number giving width of the legend in inches.} \item{ysize}{height of legend in inches} \item{lcex}{the characters expansion size for the text in the legend, see \code{\link{par}(cex=)}.} \item{inner}{the inner diameter of a hexagon in inches.} \item{style}{the hexagon style; see \code{\link{grid.hexagons}}.} \item{minarea, maxarea}{fraction of the cell area for the lowest and largest count, respectively.} \item{mincnt, maxcnt}{minimum and maximum count accepted in \code{plot}.} \item{trans}{a transformation function for the counts such as \code{\link{sqrt}}.} \item{inv}{the inverse transformation function.} \item{colorcut}{numeric vector of values covering [0, 1] the determine hexagon color classes boundaries and hexagon legend size boundaries.} \item{border}{argument for \code{\link{polygon}()}. Draw the border for each hexagon.} \item{density}{argument for \code{\link{polygon}()} filling. A \code{0} causes the polygon not to be filled.} \item{pen}{color argument used for \code{\link{polygon}(col = .)}. Determines the color with which the polygon will be filled.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{leg.unit}{unit to use}%FIXME } \details{ The \code{plot} method for \code{\link{hexbin}} objects calls this function to produce a legend by setting the graphics parameters, so \code{hex.legend} itself is not a standalone function. The legend function is \bold{preliminary}. Later version will include refinements and handle extreme cases (small and large) for cell size and counts. See the \bold{Details} section of \code{\link{grid.hexagons}}'s help page. } \value{ This function does not return any value. } \references{ see in \code{\link{grid.hexagons}}.} \author{ Dan Carr ported by Nicholas Lewin-Koh } \seealso{\code{\link{hexbin}}, \code{\link{grid.hexagons}}, % FIXME \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, % \code{\link{hcell}}, \code{\link{hcell2xy}}, \code{\link{gplot.hexbin}},% \code{\link{hboxplot}},% \code{\link{hdiffplot}}, % \code{\link{hmatplot}} } \examples{ ## Not a stand alone function; typically only called from plot.hexbin() %% Hence we should not run it here! %% FIXME: Improve hex.legend() such that it *can* be added to plots !!! \dontrun{ grid.hexlegend(legend = 2, ysize = 1,lcex=8,inner=0.2, maxcnt = 100, colorcut = c(0.5,0.5)) } } \keyword{aplot} hexbin/man/hdiffplot.Rd0000644000175100001440000001241311551510077014571 0ustar hornikusers\name{hdiffplot} \alias{hdiffplot} \title{Plot of Domain and Median Differences of Two "hexbin" Objects} \description{ Let \code{bin1} and \code{bin2} represent two \code{\link{hexbin}} objects with scaling, plot shapes, and bin sizes. This plot distinguishes cells unique to \code{bin1}, cells in common, and cells unique to \code{bin2} using color. When the erode components are present, color also distinguishes the two erosion medians. An arrow shows the vector from the median of \code{bin1} to the median of \code{bin2}. } \usage{ hdiffplot(bin1, bin2 = NULL, xbnds, ybnds, focus = NULL,% if(is.null(bin2)) 1:length(bin1) else c(1, 2), col.control = list(medhex = "white", med.bord = "black", focus = NULL, focus.border = NULL, back.col = "grey"), arrows = TRUE, size = unit(0.1, "inches"), lwd = 2, eps = 1e-6, unzoom = 1.08, clip="off", xlab = "", ylab = "", main = deparse(mycall), \dots) } \arguments{ \item{bin1, bin2}{two objects of class \code{\link{hexbin}}.} \item{xbnds,ybnds}{global x- and y-axis plotting limits. Used primarily for multiple comparison plots.} %%%------- FIXME -------- \item{focus}{a vector of integers specifying which hexbin objects should be treated as focal. Excluded hexbins are treated as background.} \item{col.control}{a list for detailed color control.}%% <<< FIXME \item{arrows}{a logical indicating wheter or not to draw arrows between the focal hexbin objects median cells.} %not yet \item{density}{fill arguments to polygon} %not yet \item{pen}{pen numbers for polgyon} \item{border}{border arguments to polygon} \item{size}{arrow type size in inches.} \item{eps}{distance criteria for distinct medians} \item{unzoom}{plot limit expansion factor when xbnds is missing} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{lwd}{Line width for arrows, ignored when \code{arrows=FALSE} or when bins have no erosion component} \item{xlab}{label for x-axis} \item{ylab}{label for y-axis} \item{main}{main title for the plot; automatically constructed by default.} \item{\dots}{...............} } % \value{ % ((currently unspecified --- proposals are welcome))%% FIXME % } \details{ The hexbin objects for comparison, \code{bin1} and \code{bin2}, must have the same plotting limits and cell size. The plot produces a comparison overlay of the cells in the two objects. If external global scaling is not supplied, the algorithm determines plotting limits to increase resolution. For example, the objects may be the result of the \code{\link{erode.hexbin}()} and include only high count cells containing 50 of the counts. The density, border, and pen arguments correspond to the polygon function calls for plotting six types of cells. The cell types are respectively: \tabular{l}{ unique cells of bin1,\cr joint cells,\cr unique cells of bin2,\cr median cell of bin1,\cr median cell of bin2,\cr median cell if identical.\cr } The \code{erode} components of the hexbin objects must be present for the medians to plot. The algorithm select a single cell for the median if there are algorithmic ties. %% FIXME: no 'pen' argument anymore .. (?) The \code{pen} numbers for types of cells start at Pen 2. Pen 1 is presumed black. The suggested six additional colors are light blue, light gray, light red, blue, red, and black. Carr (1991) shows an example for black and white printing. That plot changes the six colors to light gray, dark gray, white, black, black, and black. It changes the 4th, 5th, and 6th argument of border to TRUE. It also changes 4th, 5th and 6th argument of density to 0. In other words cells in common do not show and medians cells appear as outlines. When \code{xbnds} is missing, the plot changes graphics parameters and resets them. The function also zooms in based on the available data to provide increased resolution. } \references{ see in \code{\link{grid.hexagons}}.}%>> ./hexagons.Rd \seealso{ \code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, % MISSING: hthin, \code{\link{hcell2xy}}, % \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, % \code{\link{hmatplot}}, \code{\link{grid.hexagons}}, \code{\link{grid.hexlegend}}. } \examples{ ## Comparison of two bivariate boxplots x1 <- rnorm(10000) y1 <- rnorm(10000) x2 <- rnorm(10000,mean=.5) y2 <- rnorm(10000,mean=.5) xbnds <- range(x1,x2) ybnds <- range(y1,y2) bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds) bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds) erodebin1 <- erode.hexbin(smooth.hexbin(bin1)) erodebin2 <- erode.hexbin(smooth.hexbin(bin2)) hdiffplot(erodebin1,erodebin2) ## Compare *three* of them: -------------------- x3 <- rnorm(10000,mean=-1) y3 <- rnorm(10000,mean=-.5) xbnds <- range(x1,x2,x3) ybnds <- range(y1,y2,y3) bin1 <- hexbin(x1,y1,xbnds=xbnds,ybnds=ybnds) bin2 <- hexbin(x2,y2,xbnds=xbnds,ybnds=ybnds) bin3 <- hexbin(x3,y3,xbnds=xbnds,ybnds=ybnds) erodebin1 <- erode.hexbin(smooth.hexbin(bin1)) erodebin2 <- erode.hexbin(smooth.hexbin(bin2)) erodebin3 <- erode.hexbin(smooth.hexbin(bin3)) bnlst <- list(b1=erodebin1, b2=erodebin2, b3=erodebin3) hdiffplot(bnlst) } \keyword{hplot} hexbin/man/hexpolygon.Rd0000644000175100001440000000537012371431670015014 0ustar hornikusers\name{hexpolygon} \alias{hexpolygon} \alias{hexcoords} \title{Hexagon Coordinates and Polygon Drawing} \description{ Simple \sQuote{low-level} function for computing and drawing hexagons. Can be used for \sQuote{grid} (package \pkg{grid}) or \sQuote{traditional} (package \pkg{graphics}) graphics. } \usage{ hexcoords(dx, dy = NULL, n = 1, sep = NULL) hexpolygon(x, y, hexC = hexcoords(dx, dy, n = 1), dx, dy = NULL, fill = 1, border = 0, hUnit = "native", ...) } \arguments{ \item{dx,dy}{horizontal and vertical width of the hexagon(s).} \item{n}{number of hexagon \dQuote{repeats}.} \item{sep}{separator value to be put between coordinates of different hexagons. The default, \code{NULL} doesn't use a separator.} \item{x,y}{numeric vectors of the same length specifying the hexagon \emph{centers} around which to draw.} \item{hexC}{a list as returned from \code{hexcoords()}. Its component \code{no.sep} determines if grid or traditional graphics are used. The default (via default of \code{hexcoords}) is now to use grid graphics.} \item{fill,border}{passed to \code{\link[grid]{grid.polygon}} (for \pkg{grid}).} \item{hUnit}{string or \code{NULL} determining in which units (x,y) values are.} \item{\dots}{further arguments passed to \code{\link{polygon}} (for \pkg{graphics}).} } \value{ \code{hexcoords()} returns a list with components \item{x,y}{numeric vectors of length \eqn{n \times 6}{n * 6} (or \eqn{n \times 7}{n * 7} if \code{sep} is not NULL) specifying the hexagon polygon coordinates (with \code{sep} appended to each 6-tuple).} \item{no.sep}{a logical indicating if \code{sep} was \code{NULL}.} \code{hexpolygon} returns what its last \code{\link[grid]{grid.polygon}(.)} or \code{\link{polygon}(.)} call returns. } \author{Martin Maechler, originally.} \seealso{\code{\link{grid.hexagons}} which builds on these.} \examples{ str(hexcoords(1, sep = NA)) # multiple of (6 + 1) str(hexcoords(1, sep = NULL))# no separator -> multiple of 6 \dontshow{ stopifnot(3 * (6+1) == sapply(hexcoords(2, n = 3, sep = NA)[1:2], length), 6 == sapply(hexcoords(1)[1:2], length)) set.seed(1001) } ## hexpolygon()s: x <- runif(20, -2, 2) y <- x + rnorm(20) ## 1) traditional 'graphics' plot(x,y, asp = 1, "plot() + hexpolygon()") hexpolygon(x,y, dx = 0.1, density = 25, col = 2, lwd = 1.5) ## 2) "grid" : addBit <- function(bnds, f = 0.05) bnds + c(-f, f) * diff(bnds) sc <- addBit(rxy <- range(x,y))# same extents (cheating asp=1) library("grid") grid.newpage() pushViewport(plotViewport(.1+c(4,4,2,1), xscale = sc, yscale = sc)) grid.rect() grid.xaxis() grid.yaxis() grid.points(x,y) hexpolygon(x,y, hexcoords(dx = 0.1, sep=NULL), border = "blue", fill=NA) popViewport() } \keyword{dplot} \keyword{aplot} hexbin/man/hexList.Rd0000644000175100001440000000305212102122210014206 0ustar hornikusers\name{hexList} \alias{hexList} \alias{hexbinList-class} \alias{coerce,list,hexbinList-method} \title{Conditional Bivariate Binning into Hexagon Cells } \description{ Creates a list of \code{\link{hexbin}} objects. Basic components are a cell id and a count of points falling in each occupied cell. Basic methods are \code{\link[methods]{show}()}, \code{plot()} %(\link{plot.hexbin}) and \code{\link{summary}()}, but also \code{\link{erode}}. % .. \code{\link{smooth.hexbin}} } \usage{ hexList(x, y = NULL, given = NULL, xbins = 30, shape = 1, xbnds = NULL, ybnds = NULL, xlab = NULL, ylab = NULL) } %- maybe also 'usage' for other objects documented here. \arguments{ \item{x}{ x coordinate to be binned } \item{y}{ y coordinate to be binned } \item{given}{ ..} \item{xbins}{ number of bins partitioning the range of xbnds} \item{shape}{ the \emph{shape} = yheight/xwidth of the plotting regions } \item{xbnds}{ horizontal limits of binning } \item{ybnds}{ vertical limits of binning } \item{xlab}{ character strings used as labels for \code{x} } \item{ylab}{ character strings used as labels for \code{y}} } \details{ There is also a \code{\link[methods:as]{coerce}} method to produce \code{hexbinList} objects from \code{\link{list}}s. %% i.e., \code{as(list(....), "hexbinList")} should work } \value{ If it is a LIST, use \item{comp1 }{Description of 'comp1'} \item{comp2 }{Description of 'comp2'} ... } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hexbin}}, \code{\link{hdiffplot}} } \keyword{dplot} \keyword{misc} hexbin/man/list2hexList.Rd0000644000175100001440000000066511551510077015216 0ustar hornikusers\name{list2hexList} \alias{list2hexList} \title{Convert list to hexList} \description{ Converts a list of hexbin objects with same xbnds, ybnds, shape and xbins to a \code{\link{hexList}} object. } \usage{ list2hexList(binlst) } \arguments{ \item{binlst}{A list of hexbin objects} } \value{ a \code{\link{hexList}} object } \author{Nicholas Lewin-Koh} \seealso{\code{\link{hexList}},\code{\link{hdiffplot}} } \keyword{misc} hexbin/man/gplot.hexbin.Rd0000644000175100001440000001350012371752042015212 0ustar hornikusers\name{gplot.hexbin} \alias{gplot.hexbin} \alias{plot,hexbin,missing-method} \title{Plotting Hexagon Cells with a Legend} \description{ Plots Hexagons visualizing the counts in an hexbin object. Different styles are availables. Provides a legend indicating the count representations. } \usage{ %% In future: No longer export gplot.hexbin() ! gplot.hexbin(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n,beg = 90,end = 15), xlab = "", ylab = "", main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip = "on", verbose = getOption("verbose")) %% FIXME: This is the S4 plot method for 'hexbin' %% currently also exported "standalone" - for testing,debugging.. %% we'd really don't want to repeat the argument list; use \synopsis{.} ? \S4method{plot}{hexbin,missing}(x, style = "colorscale", legend = 1.2, lcex = 1, minarea = 0.04, maxarea = 0.8, mincnt = 1, maxcnt = max(x@count), trans = NULL, inv = NULL, colorcut = seq(0, 1, length = min(17, maxcnt)), border = NULL, density = NULL, pen = NULL, colramp = function(n) LinGray(n,beg = 90,end = 15), xlab = "", ylab = "", main = "", newpage = TRUE, type = c("p", "l", "n"), xaxt = c("s", "n"), yaxt = c("s", "n"), clip = "on", verbose = getOption("verbose")) } \arguments{ \item{x}{an object of class \code{\link{hexbin}}.} % \item{y}{(required by the S4 method for \code{\link{plot}} but unused % here; must be missing)} \item{style}{string specifying the style of hexagon plot, see \code{\link{grid.hexagons}} for the possibilities.} \item{legend}{numeric width of the legend in inches of \code{FALSE}. In the latter case, or when \code{0}, no legend is not produced.} \item{lcex}{characters expansion size for the text in the legend} \item{minarea}{fraction of cell area for the lowest count} \item{maxarea}{fraction of the cell area for the largest count} \item{mincnt}{cells with fewer counts are ignored.} \item{maxcnt}{cells with more counts are ignored.} \item{trans}{\code{\link{function}} specifying a transformation for the counts such as \code{sqrt}.} % FIXME: use better description of these in hexagons() -- or use same % ---- help page ?! \item{inv}{the inverse transformation of \code{trans}.} \item{colorcut}{vector of values covering [0, 1] that determine hexagon color class boundaries and hexagon legend size boundaries. Alternatively, an integer (\code{<= maxcnt}) specifying the \emph{number} of equispaced colorcut values in [0,1].} \item{border, density, pen}{color for polygon borders and filling of each hexagon drawn, passed to \code{\link{grid.hexagons}}.} \item{colramp}{function accepting an integer \code{n} as an argument and returning n colors.} \item{xlab, ylab}{x- and y-axis label.} \item{main}{main title.} \item{newpage}{should a new page start?.} \item{type, xaxt, yaxt}{strings to be used (when set to \code{"n"}) for suppressing the plotting of hexagon symbols, or the x- or y-axis, respectively.} \item{clip}{either 'on' or 'off' are the allowed arguments, when on everything is clipped to the plotting region.} \item{verbose}{logical indicating if some diagnostic output should happen.} \item{\dots}{all arguments of \code{gplot.hexbin} can also be used for the S4 \code{\link{plot}} method.} } \details{ This is the (S4) \code{\link{plot}} method for \code{\link{hexbin}} (and \code{erodebin}) objects (\link{erodebin-class}). To use the standalone function \code{gplot.hexbin()} is \bold{\emph{deprecated}}. For \code{style}, \code{minarea} etc, see the \bold{Details} section of \code{\link{grid.hexagons}}'s help page. The legend functionality is somewhat preliminary. Later versions may include refinements and handle extreme cases (small and large) for cell size and counts. } \value{ invisibly, a list with components \item{plot.vp}{the \code{\link{hexViewport}} constructed and used.} \item{legend.vp}{if a legend has been produced, its \code{\link[grid]{viewport}}.} } \references{ see in \code{\link{grid.hexagons}}.} \author{ Dan Carr \email{dcarr@voxel.galaxy.gmu.edu}, ported by Nicholas Lewin-Koh \email{kohnicho@comp.nus.edu.sg} and Martin Maechler. } \seealso{\code{\link{hexbin}}, \code{\link{hexViewport}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, \code{\link{hcell2xy}}, \code{\link{hboxplot}}, \code{\link{hdiffplot}}. %%, \code{\link{hmatplot}}. } \examples{ ## 1) simple binning of spherical normal: x <- rnorm(10000) y <- rnorm(10000) bin <- hexbin(x,y) ## Plot method for hexbin ! ## ---- ------ -------- plot(bin) # nested lattice plot(bin, style= "nested.lattice") # controlling the colorscheme plot(bin, colramp=BTY, colorcut=c(0,.1,.2,.3,.4,.6,1)) ## 2) A mixture distribution x <- c(rnorm(5000),rnorm(5000,4,1.5)) y <- c(rnorm(5000),rnorm(5000,2,3)) bin <- hexbin(x,y) pens <- cbind(c("#ECE2F0","#A6BDDB","#1C9099"), c("#FFF7BC","#FEC44F","#D95F0E")) plot(bin, style = "nested.lattice", pen=pens) # now really crazy plot(bin, style = "nested.lattice", pen=pens,border=2,density=35) # lower resolution binning and overplotting with counts bin <- hexbin(x,y,xbins=25) P <- plot(bin, style="lattice", legend=FALSE, minarea=1, maxarea=1, border="white") ## %% FIXME! library("grid") pushHexport(P$plot.vp) xy <- hcell2xy(bin) # to show points rather than counts : grid.points(x,y,pch=18,gp=gpar(cex=.3,col="green")) grid.text(as.character(bin@count), xy$x,xy$y, gp=gpar(cex=0.3, col="red"),default.units="native") popViewport() # Be creative, have fun! } \keyword{hplot} hexbin/man/hexVP-class.Rd0000644000175100001440000000607312371427121014752 0ustar hornikusers\name{hexVP-class} \docType{class} \alias{hexVP-class} \alias{getFig,hexVP-method} \alias{getMargins,hexVP-method} \alias{getPlt,hexVP-method} \alias{getXscale,hexVP-method} \alias{getYscale,hexVP-method} \title{Formal class "hexVP" of a Hexagon Viewport} \description{ Hexagon Viewports are \dQuote{value-added} grid viewports (see \code{\link[grid]{viewport}}) where the extra slots contain scaling and \dQuote{embedding} information. A hexViewport is created my taking the available area in the cuurent viewport on the graphics device and maximizing the amount of area with a fied aspect ratio. The default when the shape parameter is 1, is a 1:1 aspect ratio in terms of the size of the viewport, not the scale of the x and y axis. The plotting area is centered within the existing margins and the maximum size determined. Extra area is then allocated to the margins. This viewport is replicated twice, once with clipping set to "on" and once with clipping "off". This feature can be used for toggling clipping on and off while editing the plot. } \section{Objects from the Class}{ Objects are typically created by calls to \code{\link{hexViewport}()} or by low level calls of the form \code{new("hexVP", ...)}. } \section{Slots}{ \describe{ \item{\code{hexVp.off}:}{Object of class \code{"viewport"} with clipping set to off, see \code{\link[grid]{viewport}}.} \item{\code{hexVp.on}:}{Object of class \code{"viewport"}, with the same dimensions and parameters as hexVp.off, but with clipping set to on, see \code{\link[grid]{viewport}}.} \item{\code{hp.name}:}{The name of the viewport for searching a vptree}. \item{\code{mar}:}{\code{\link[grid]{unit}} vector of four margins (typically in \code{"lines"}).} \item{\code{fig}:}{\code{\link[grid]{unit}} vector of two figure sizes (typically in \code{"npc"}).} \item{\code{plt}:}{\code{\link[grid]{unit}} vector of two figure sizes (typically in \code{"npc"}).} %% MM {FIXME?}: Is n't this simply ``xlim'' - then call it so! %% NL, yes it is, but xscale and yscale is the parameters used by %% grid. \item{\code{shape}:}{The shape parameter from the plotted \code{\link[hexbin]{hexbin}} object.} \item{\code{xscale}:}{numeric of length two specifying x-range.} \item{\code{yscale}:}{numeric of length two specifying y-range.} } } \section{Methods}{ These are methods accessing the slots of corresponding name. \describe{ \item{getFig}{\code{signature(hvp = "hexVP")}: ... } \item{getMargins}{\code{signature(hvp = "hexVP")}: ... } \item{getPlt}{\code{signature(hvp = "hexVP")}: ... } \item{getXscale}{\code{signature(hvp = "hexVP")}: ... } \item{getYscale}{\code{signature(hvp = "hexVP")}: ... } } } \author{ Nicholas Lewin-Koh \email{kohnicho@comp.nus.edu.sg}. } \seealso{ The constructor function \code{\link{hexViewport}}. \code{\link{hexbin}}, and its S4 plotting method, \code{\link{gplot.hexbin}}. } \examples{ library("grid") example(hexViewport, echo=FALSE) ## continued: str(P$plot.vp) } \keyword{classes} hexbin/man/hexbinplot.Rd0000644000175100001440000002152511551510077014772 0ustar hornikusers\name{hexbinplot} \alias{hexbinplot} \alias{hexbinplot.formula} \alias{panel.hexbinplot} \alias{prepanel.hexbinplot} \alias{hexlegendGrob} \title{Trellis Hexbin Displays} \description{ Display of hexagonally binned data, as implemented in the \code{hexbin} packge, under the Trellis framework, with associated utilities. \code{hexbinplot} is the high level generic function, with the \code{"formula"} method doing the actual work. \code{prepanel.hexbinplot} and \code{panel.hexbinplot} are associated prepanel and panel functions. \code{hexlegendGrob} produces a suitable legend. } \usage{ hexbinplot(x, data, \dots) \method{hexbinplot}{formula}(x, data = NULL, prepanel = prepanel.hexbinplot, panel = panel.hexbinplot, groups = NULL, aspect = "xy", trans = NULL, inv = NULL, colorkey = TRUE, \dots, maxcnt, legend = NULL, legend.width = TRUE, subset) prepanel.hexbinplot(x, y, type = character(0), \dots) panel.hexbinplot(x, y, ..., groups = NULL) hexlegendGrob(legend = 1.2, inner = legend / 5, cex.labels = 1, cex.title = 1.2, style = "colorscale", minarea = 0.05, maxarea = 0.8, mincnt = 1, maxcnt, trans = NULL, inv = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n) { LinGray(n,beg = 90,end = 15) }, \dots, vp = NULL, draw = FALSE) } \arguments{ \item{x}{ For \code{hexbinplot}, the object on which method dispatch is carried out. For the \code{"formula"} methods, a formula describing the form of conditioning plot. Formulas that are valid for \code{xyplot} are acceptable. In \code{panel.hexbinplot}, the x variable. } \item{y}{ In \code{panel.hexbinplot}, the y variable. } \item{data}{For the \code{formula} method, a data frame containing values for any variables in the formula, as well as \code{groups} and \code{subset} if applicable (using \code{groups} currently causes an error with the default panel function). By default, the environment where the function was called from is used. } \item{minarea, maxarea, mincnt, maxcnt, trans, inv, colorcut, density, border, pen, colramp, style}{ see \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}} } \item{prepanel, panel, aspect}{ See \code{\link[lattice]{xyplot}}. \code{aspect="fill"} is not allowed. The current default of \code{"xy"} may not always be the best choice, often \code{aspect=1} will be more reasonable. } \item{colorkey}{logical, whether a legend should be drawn. Currently a legend can be drawn only on the right. } \item{legend.width, legend}{ width of the legend in inches when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. The name \code{legend.width} is used to avoid conflict with the standard trellis argument \code{legend}. It is possible to specify additional legends using the \code{legend} or \code{key} arguments as long as they do not conflict with the hexbin legend (i.e., are not on the right). } \item{inner}{ Inner radius in inches of hexagons in the legend when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. } \item{cex.labels, cex.title}{ in the legend, multiplier for numeric labels and text annotation respectively } \item{type}{ character vector controlling additional augmentation of the display. A \code{"g"} in \code{type} adds a reference grid, \code{"r"} adds a regression line (y on x), \code{"smooth"} adds a loess smooth } \item{draw}{ logical, whether to draw the legend grob. Useful when \code{hexlegendGrob} is used separately } \item{vp}{ grid viewport to draw the legend in } \item{\dots}{ extra arguments, passed on as appropriate. Arguments to \code{\link[hexbin:gplot.hexbin]{gplot.hexbin}}, \code{\link[lattice]{xyplot}}, \code{panel.hexbinplot} and \code{hexlegendGrob} can be supplied to the high level \code{hexbinplot} call. \code{panel.hexbinplot} calls one of two (unexported) low-level functions depending on whether \code{groups} is supplied (although specifying \code{groups} currently leads to an error). Arguments of the appropriate function can be supplied; some important ones are \describe{ \item{\code{xbins}:}{ number of hexagons covering x values. The number of y-bins depends on this, the aspect ratio, and \code{xbnds} and \code{ybnds}} \item{\code{xbnds, ybnds}:}{ Numeric vector specifying range of values that should be covered by the binning. In a multi-panel display, it is not necessarily a good idea to use the same bounds (which along with \code{xbins} and the aspect ratio determine the size of the hexagons) for all panels. For example, when data is concentrated in small subregions of different panels, more detail will be shown by using smaller hexagons covering those regions. To control this, \code{xbnds} and \code{ybnds} can also be character strings \code{"panel"} or \code{"data"} (which are not very good names and may be changed in future). In the first case, the bounds are taken to be the limits of the panel, in the second case, the limits of the data (packet) in that panel. Note that all panels will have the same limits (enough to cover all the data) by default if \code{relation="free"} in the standard trellis argument \code{scales}, but not otherwise.} } } \item{groups}{ in \code{hexbinplot}, a grouping variable that is evaluated in \code{data}, and passed on to the panel function. } \item{subset}{ an expression that is evaluated in evaluated in \code{data} to produce a logical vector that is used to subset the data before being used in the plot. } } \details{ The panel function \code{panel.hexbinplot} creates a hexbin object from data supplied to it and plots it using \code{\link[hexbin:grid.hexagons]{grid.hexagons}}. To make panels comparable, all panels have the same \code{maxcnt} value, by default the maximum count over all panels. This default value can be calculated only if the aspect ratio is known, and so \code{aspect="fill"} is not allowed. The default choice of aspect ratio is different from the choice in \code{hexbin} (namely, \code{1}), which may sometimes give better results for multi-panel displays. \code{xbnds} and \code{ybnds} can be numeric range vectors as in \code{hexbin}, but they can also be character strings specifying whether all panels should have the same bins. If they are not, then bins in different panels could be of different sizes, in which case \code{style="lattice"} and \code{style="centroids"} should be interpreted carefully. The dimensions of the legend and the size of the hexagons therein are given in absolute units (inches) by \code{legend.width} and \code{inner} only when \code{style} is \code{"nested.lattice"} or \code{"nested.centroids"}. For other styles, the dimensions of the legend are determined relative to the plot. Specifically, the height of the legend is the same as the height of the plot (the panel and strip regions combined), and the width is the minimum required to fit the legend in the display. This is different in some ways from the \code{hexbin} implementation. In particular, the size of the hexagons in the legend are completely unrelated to the sizes in the panels, which is pretty much unavoidable because the sizes need not be the same across panels if \code{xbnds} or \code{ybnds} is \code{"data"}. The size of the hexagons encode information when \code{style} is \code{"lattice"} or \code{"centroids"}, consequently a warning is issued when a legend is drawn with wither of these styles. } \value{ \code{hexbinplot} produces an object of class \code{"trellis"}. The \code{update} method can be used to update components of the object and the \code{print} method (usually called by default) will plot it on an appropriate plotting device. \code{hexlegendGrob} produces a \code{"grob"} (grid object). } \author{ Deepayan Sarkar \email{deepayan@stat.wisc.edu}} \seealso{ \code{\link{hexbin}}, \code{\link[lattice]{xyplot}} } \examples{ mixdata <- data.frame(x = c(rnorm(5000),rnorm(5000,4,1.5)), y = c(rnorm(5000),rnorm(5000,2,3)), a = gl(2, 5000)) hexbinplot(y ~ x, mixdata, aspect = 1, trans = sqrt, inv = function(x) x^2) hexbinplot(y ~ x | a, mixdata) hexbinplot(y ~ x | a, mixdata, style = "lattice", xbnds = "data", ybnds = "data") hexbinplot(y ~ x | a, mixdata, style = "nested.centroids") hexbinplot(y ~ x | a, mixdata, style = "nested.centroids", border = FALSE, type = c("g", "smooth")) } \keyword{dplot} hexbin/man/grid.hexagons.Rd0000644000175100001440000002045012371752004015351 0ustar hornikusers\name{grid.hexagons} \alias{grid.hexagons} \title{Add Hexagon Cells to Plot} \description{ Plots cells in an hexbin object. The function distinquishes among counts using 5 different styles. This function is the hexagon plotting engine from the \code{plot} method for \code{\link{hexbin}} objects. } \usage{ grid.hexagons(dat, style = c("colorscale", "centroids", "lattice", "nested.lattice", "nested.centroids", "constant.col"), use.count=TRUE, cell.at=NULL, minarea = 0.05, maxarea = 0.8, check.erosion = TRUE, mincnt = 1, maxcnt = max(dat@count), trans = NULL, colorcut = seq(0, 1, length = 17), density = NULL, border = NULL, pen = NULL, colramp = function(n){ LinGray(n,beg = 90, end = 15) }, def.unit= "native", verbose = getOption("verbose")) } \arguments{ \item{dat}{an object of class \code{hexbin}, see \code{\link{hexbin}}.} \item{style}{character string specifying the type of plotting; must be (a unique abbrevation) of the values given in \sQuote{Usage} above.} \item{use.count}{logical specifying if counts should be used.} \item{cell.at}{numeric vector to be plotted instead of counts, must besame length as the number of cells.} \item{minarea}{numeric, the fraction of cell area for the lowest count.} \item{maxarea}{the fraction of the cell area for the largest count.} \item{check.erosion}{logical indicating only eroded points should be used for \code{"erodebin"} objects; simply passed to \code{\link{hcell2xy}}, see its documentation.} \item{mincnt}{numeric; cells with counts smaller than \code{mincnt} are not shown.} \item{maxcnt}{cells with counts larger than this are not shown.} \item{trans}{a transformation function (or \code{NULL}) for the counts, e.g., \code{\link{sqrt}}.} \item{colorcut}{a vector of values covering [0, 1] which determine hexagon color class boundaries or hexagon size boundaries -- for \code{style = "colorscale"} only.} \item{density}{\code{\link[grid]{grid.polygon}} argument for shading. 0 causes the polygon not to be filled. \emph{This is not implemented (for \code{\link[grid]{grid.polygon}}) yet}.} \item{border}{\code{\link[grid]{grid.polygon}()} argument. Draw the border for each hexagon.} \item{pen}{colors for \code{\link[grid]{grid.polygon}()}. Determines the color with which the polygon will be filled.} \item{colramp}{function of an integer argument \code{n} returning n colors. \code{n} is determined }%% how? FIXME \item{def.unit}{default \code{\link[grid]{unit}} to be used.}% FIXME \item{verbose}{logical indicating if some diagnostic output should happen.} } \section{SIDE EFFECTS}{Adds hexagons to the plot.} \details{ The six plotting styles have the following effect: \describe{ \item{\code{style="lattice"} or \code{"centroids"}:}{ Plots the hexagons in different sizes based on counts. The \code{"lattice"} version centers the hexagons at the cell centers whereas \code{"centroids"} moves the hexagon centers close to the center of mass for the cells. In all cases the hexagons will not plot outside the cell unless \code{maxarea > 1}. Counts are rescaled into the interval [0,1] and colorcuts determine the class boundaries for sizes and counts. The pen argument for this style should be a single color or a vector of colors of \code{length(bin@count)}.} \item{\code{style="colorscale"}:}{ Counts are rescaled into the interval [0,1] and colorcuts determines the class boundaries for the color classes. For this style, the function passed as \code{colramp} is used to define the n colors for the n+1 color cuts. The pen argument is ignored. %% S-plus: In motif color options try polygon: black 16 white See \code{\link{LinGray}} for the default \code{colramp} and alternative \dQuote{color ramp} functions. } \item{\code{style="constant.col"}:}{ This is an even simpler alternative to \code{"colorscale"}, using constant colors (determined \code{pen} optionally). } \item{\code{style="nested.lattice"} and \code{"nested.centroids"}:}{ Counts are partitioned into classes by power of 10. The encoding nests hexagon size within powers of 10 color contours. If the pen argument is used it should be a matrix of colors with 2 columns and either \code{ceiling(log10(max(bin@count)))} or \code{length(bin@count)} rows. The default uses the \R color palatte so that pens numbers 2-11 determine colors for completely filled cell Pen 2 is the color for 1's, Pen 3 is the color for 10's, etc. Pens numbers 12-21 determine the color of the foreground hexagons. The hexagon size shows the relative count for the power of 10. Different color schemes give different effects including 3-D illusions %% S-plus : %% One motif color option for the first 4 powers is black \#BBB \#36F %% \#0E3 \#F206 \#FFF4 \#FFF %% %% A second option is for the first 5 power is black \#FFF \#08F \#192 %% \#F11 \#FF04 \#000 \#999 \#5CF \#AFA \#FAAF \#000 } } \emph{Hexagon size encoding \code{minarea} and \code{maxarea}} determine the area of the smallest and largest hexagons plotted. Both are expressed fractions of the bin cell size. Typical values might be .04 and 1. When both values are 1, all plotted hexagons are bin cell size, if \code{maxarea} is greater than 1 than hexagons will overlap. This is sometimes interesting with the lattice and centroid styles. \emph{Count scaling} \code{relcnt <- (trans(cnt)-trans(mincnt)) / (trans(maxcnt)-trans(mincnt))} \cr \code{area <- minarea + relcnt*maxarea} By default the transformation \code{trans()} is the identity function. The legend routine requires the transformation inverse for some options. \emph{Count windowing \code{mincnt} and \code{maxcnt}} Only routine only plots cells with cnts in [mincnts, maxcnts] } \references{ Carr, D. B. (1991) Looking at Large Data Sets Using Binned Data Plots, pp. 7--39 in \emph{Computing and Graphics in Statistics}; Eds. A. Buja and P. Tukey, Springer-Verlag, New York. } \author{ Dan Carr ; ported and extended by Nicholas Lewin-Koh \email{nikko@hailmail.net}. } \seealso{\code{\link{hexbin}}, \code{\link{smooth.hexbin}}, \code{\link{erode.hexbin}}, \code{\link{hcell2xy}},% \code{\link{hcell}}, \code{\link{gplot.hexbin}}, \code{\link{hboxplot}}, \code{\link{hdiffplot}}, \code{\link{grid.hexlegend}}% \code{\link{hmatplot}} } \examples{ set.seed(506) x <- rnorm(10000) y <- rnorm(10000) # bin the points bin <- hexbin(x,y) # Typical approach uses plot( ) which controls the plot shape : plot(bin, main = "Bivariate rnorm(10000)") ## but we can have more manual control: # A mixture distribution x <- c(rnorm(5000),rnorm(5000,4,1.5)) y <- c(rnorm(5000),rnorm(5000,2,3)) hb2 <- hexbin(x,y) # Show color control and overplotting of hexagons ## 1) setup coordinate system: P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 ## 2) add hexagons (in the proper viewport): pushHexport(P$plot.vp) grid.hexagons(hb2, style= "lattice", border = gray(.1), pen = gray(.6), minarea = .1, maxarea = 1.5) library("grid") popViewport() ## How to treat 'singletons' specially: P <- plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 pushHexport(P$plot.vp) grid.hexagons(hb2, style= "nested.centroids", mincnt = 2)# not the single ones grid.hexagons(hb2, style= "centroids", maxcnt = 1, maxarea=0.04)# single points popViewport() %% FIXME --- this would mix grid- and traditional-graphics %% ----- would need grid-graphics for 'gpclib' -- aaargs... % # And if we had all the information... % if(require(gpclib)){ % h1 <- chull(x[1:5000], y[1:5000]) % h2 <- chull(x[5001:10000], y[5001:10000]) % h2 <- h2+5000 % h1 <- as(cbind(x[1:5000],y [1:5000])[h1, ], "gpc.poly") % h2 <- as(cbind(x,y)[h2, ], "gpc.poly") % plot(hb2, type="n", main = "Bivariate mixture (10000)")# asp=1 % % plot(h1,poly.args = list(col ="#CCEBC5"),add = TRUE) % plot(h2,poly.args = list(col ="#FBB4AE"),add = TRUE) % plot(intersect(h1, h2), poly.args = list(col = 2), add = TRUE) % grid.hexagons(hb2, style= "centroids", border = gray(.1), pen = gray(.6), % minarea = .1, maxarea = 1.5) % } } \keyword{aplot} hexbin/man/hcell2xyInt.Rd0000644000175100001440000000254411551510077015023 0ustar hornikusers\name{hcell2xyInt} \alias{hcell2xyInt} %- Also NEED an '\alias' for EACH other topic documented here. \title{Change cell ids to 2d integer coordinate system} \description{ Transforms the cell representation of a a lattice into a 2d integer coordinate system. } \usage{ hcell2xyInt(hbin, xbins=NULL, xbnds=NULL, ybnds=NULL, shape=NULL) } \arguments{ \item{hbin}{a object of class \code{"hexbin"}, typically produced by \code{\link{hexbin}(*)}.} \item{xbins}{the number of bins partitioning the range of xbnds.} \item{xbnds, ybnds}{horizontal and vertical limits of the binning region in x or y units respectively; must be numeric vector of length 2.} \item{shape}{the \emph{shape} = yheight/xwidth of the plotting regions.} } \details{ Takes a grid defined by either the hexbin parameters or dimen in a hexbin object and translates the cell ids for the grid into 2d integer coordinates. } \value{ An integer matrix with two columns, i and j representing the integer xy coordinates of the hexagon grid. \item{i}{Integer coordiante of the rows, increases from bottom to top} \item{j}{Integer coordiante of the columns, increases from left to right} } \author{Nicholas Lewin-Koh } \seealso{\code{\link{hcell2xy}}} \examples{ x<-rnorm(10000) y<-rnorm(10000) hbin<-hexbin(x,y) ijInt<-hcell2xyInt(hbin) } \keyword{dplot} \keyword{misc} hexbin/man/colramp.Rd0000644000175100001440000000332511551510077014251 0ustar hornikusers\name{ColorRamps} \title{Color Ramps on Perceptually Linear Scales} \alias{ColorRamps} \alias{LinGray} \alias{BTC} \alias{BTY} \alias{LinOCS} \alias{heat.ob} \alias{magent} \alias{plinrain} \description{ Functions for returning colors on perceptually linear scales, where steps correspond to \sQuote{just detectable differences}. } \usage{ LinGray (n, beg=1, end=92) BTC (n, beg=1, end=256) LinOCS (n, beg=1, end=256) heat.ob (n, beg=1, end=256) magent (n, beg=1, end=256) plinrain(n, beg=1, end=256) } \arguments{ \item{n}{number of colors to return from the ramp} \item{beg}{begining of ramp, integer from 1-255} \item{end}{end of ramp, integer from 1-255} } \value{ returns an array of colors } \details{ Several precalulated color ramps, that are on a perceptually linear color scale. A perceptually linear color scale is a scale where each jump corresponds to a \dQuote{just detectable difference} in color and the scale is percieved as linear by the human eye (emprically determined). When using the ramps, if \code{beg} is less than \code{end} the ramp will be reversed. } \references{ Haim Levkowitz (1997) \emph{Color Theory and Modeling for Computer Graphics, Visualization, and Multimedia Applications}. Kluwer Academic Publishers, Boston/London/Dordrecht. \url{http://www.cs.uml.edu/~haim/ColorCenter/} } \seealso{ \code{\link[grDevices:palettes]{rainbow}}, \code{\link[grDevices:palettes]{terrain.colors}}, \code{\link[grDevices]{rgb}}, \code{\link[grDevices]{hsv}} } \examples{ h <- hexbin(rnorm(10000),rnorm(10000)) plot(h, colramp= BTY) ## looks better if you shave the tails: plot(h, colramp= function(n){LinOCS(n,beg=15,end=225)}) } \author{Nicholas Lewin-Koh} \keyword{color} hexbin/man/NHANES.Rd0000644000175100001440000000365412102122164013562 0ustar hornikusers\name{NHANES} \alias{NHANES} \docType{data} \title{NHANES Data : National Health and Nutrition Examination Survey} \usage{data(NHANES)} \description{ This is a somewhat large interesting dataset, a data frame of 15 variables (columns) on 9575 persons (rows). } \format{ This data frame contains the following columns: \describe{ \item{Cancer.Incidence}{binary factor with levels \code{No} and \code{Yes}.} \item{Cancer.Death}{binary factor with levels \code{No} and \code{Yes}.} \item{Age}{numeric vector giving age of the person in years.} \item{Smoke}{a factor with levels \code{Current}, \code{Past}, \code{Nonsmoker}, and \code{Unknown}.} \item{Ed}{numeric vector of \eqn{\{0,1\}} codes giving the education level.} \item{Race}{numeric vector of \eqn{\{0,1\}} codes giving the person's race.%% FIXME : 0 = ? 1 = ? } \item{Weight}{numeric vector giving the weight in kilograms} \item{BMI}{numeric vector giving Body Mass Index, i.e., \code{Weight/Height^2} where Height is in meters, and missings (61\% !) are coded as \code{0} originally.}%% rather FIXME? \item{Diet.Iron}{numeric giving Dietary iron.} \item{Albumin}{numeric giving albumin level in g/l.} \item{Serum.Iron}{numeric giving Serum iron in \eqn{\mu}{u}g/l.} \item{TIBC}{numeric giving Total Iron Binding Capacity in \eqn{\mu}{u}g/l.} \item{Transferin}{numeric giving Transferin Saturation which is just \code{100*serum.iron/TIBC}.} \item{Hemoglobin}{numeric giving Hemoglobin level.} \item{Sex}{a factor with levels \code{F} (female) and \code{M} (male).} } } \examples{ data(NHANES) summary(NHANES) ## Missing Data overview : nNA <- sapply(NHANES, function(x)sum(is.na(x))) cbind(nNA[nNA > 0]) # Which are just these 6 : \dontrun{ Diet.Iron 141 Albumin 252 Serum.Iron 1008 TIBC 853 Transferin 1019 Hemoglobin 759 }%dont } \keyword{datasets}